Changed reflection to use (much faster) ReflectASM

This commit is contained in:
nathan 2015-02-08 14:51:30 +01:00
parent 2e7cc11799
commit 220e522ff0
6 changed files with 119 additions and 152 deletions

View File

@ -1,6 +1,6 @@
package net.engio.mbassy.dispatch; package net.engio.mbassy.dispatch;
import java.lang.reflect.Method; import com.esotericsoftware.reflectasm.MethodAccess;
/** /**
* A handler invocation encapsulates the logic that is used to invoke a single * A handler invocation encapsulates the logic that is used to invoke a single
@ -28,7 +28,7 @@ public interface IHandlerInvocation {
* type that the handler consumes * type that the handler consumes
* @param handler The handler (method) that will be called via reflection * @param handler The handler (method) that will be called via reflection
*/ */
void invoke(Object listener, Method handler, Object message) throws Throwable; void invoke(Object listener, MethodAccess handler, int methodIndex, Object message) throws Throwable;
/** /**
* Invoke the message delivery logic of this handler * Invoke the message delivery logic of this handler
@ -39,7 +39,7 @@ public interface IHandlerInvocation {
* type that the handler consumes * type that the handler consumes
* @param handler The handler (method) that will be called via reflection * @param handler The handler (method) that will be called via reflection
*/ */
void invoke(Object listener, Method handler, Object message1, Object message2) throws Throwable; void invoke(Object listener, MethodAccess handler, int methodIndex, Object message1, Object message2) throws Throwable;
/** /**
* Invoke the message delivery logic of this handler * Invoke the message delivery logic of this handler
@ -50,7 +50,7 @@ public interface IHandlerInvocation {
* type that the handler consumes * type that the handler consumes
* @param handler The handler (method) that will be called via reflection * @param handler The handler (method) that will be called via reflection
*/ */
void invoke(Object listener, Method handler, Object message1, Object message2, Object message3) throws Throwable; void invoke(Object listener, MethodAccess handler, int methodIndex, Object message1, Object message2, Object message3) throws Throwable;
/** /**
* Invoke the message delivery logic of this handler * Invoke the message delivery logic of this handler
@ -61,5 +61,5 @@ public interface IHandlerInvocation {
* type that the handler consumes * type that the handler consumes
* @param handler The handler (method) that will be called via reflection * @param handler The handler (method) that will be called via reflection
*/ */
void invoke(Object listener, Method handler, Object... message) throws Throwable; void invoke(Object listener, MethodAccess handler, int methodIndex, Object... message) throws Throwable;
} }

View File

@ -1,6 +1,6 @@
package net.engio.mbassy.dispatch; package net.engio.mbassy.dispatch;
import java.lang.reflect.Method; import com.esotericsoftware.reflectasm.MethodAccess;
/** /**
* Uses reflection to invoke a message handler for a given message. * Uses reflection to invoke a message handler for a given message.
@ -17,22 +17,22 @@ public class ReflectiveHandlerInvocation implements IHandlerInvocation {
} }
@Override @Override
public void invoke(final Object listener, Method handler, final Object message) throws Throwable { public void invoke(final Object listener, final MethodAccess handler, final int methodIndex, final Object message) throws Throwable {
handler.invoke(listener, message); handler.invoke(listener, methodIndex, message);
} }
@Override @Override
public void invoke(final Object listener, Method handler, final Object message1, final Object message2) throws Throwable { public void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object message1, final Object message2) throws Throwable {
handler.invoke(listener, message1, message2); handler.invoke(listener, methodIndex, message1, message2);
} }
@Override @Override
public void invoke(final Object listener, Method handler, final Object message1, final Object message2, final Object message3) throws Throwable { public void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object message1, final Object message2, final Object message3) throws Throwable {
handler.invoke(listener, message1, message2, message3); handler.invoke(listener, methodIndex, message1, message2, message3);
} }
@Override @Override
public void invoke(final Object listener, Method handler, final Object... messages) throws Throwable { public void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object... messages) throws Throwable {
handler.invoke(listener, messages); handler.invoke(listener, methodIndex, messages);
} }
} }

View File

@ -1,6 +1,6 @@
package net.engio.mbassy.dispatch; package net.engio.mbassy.dispatch;
import java.lang.reflect.Method; import com.esotericsoftware.reflectasm.MethodAccess;
/** /**
* Synchronizes message handler invocations for all handlers that specify @Synchronized * Synchronizes message handler invocations for all handlers that specify @Synchronized
@ -19,30 +19,30 @@ public class SynchronizedHandlerInvocation implements IHandlerInvocation {
} }
@Override @Override
public void invoke(final Object listener, Method handler, final Object message) throws Throwable { public void invoke(final Object listener, final MethodAccess handler, final int methodIndex, final Object message) throws Throwable {
synchronized (listener) { synchronized (listener) {
this.delegate.invoke(listener, handler, message); this.delegate.invoke(listener, handler, methodIndex, message);
} }
} }
@Override @Override
public void invoke(final Object listener, Method handler, final Object message1, final Object message2) throws Throwable { public void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object message1, final Object message2) throws Throwable {
synchronized (listener) { synchronized (listener) {
this.delegate.invoke(listener, handler, message1, message2); this.delegate.invoke(listener, handler, methodIndex, message1, message2);
} }
} }
@Override @Override
public void invoke(final Object listener, Method handler, final Object message1, final Object message2, final Object message3) throws Throwable { public void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object message1, final Object message2, final Object message3) throws Throwable {
synchronized (listener) { synchronized (listener) {
this.delegate.invoke(listener, handler, message1, message2, message3); this.delegate.invoke(listener, handler, methodIndex, message1, message2, message3);
} }
} }
@Override @Override
public void invoke(final Object listener, Method handler, final Object... messages) throws Throwable { public void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object... messages) throws Throwable {
synchronized (listener) { synchronized (listener) {
this.delegate.invoke(listener, handler, messages); this.delegate.invoke(listener, handler, methodIndex, messages);
} }
} }
} }

View File

@ -1,6 +1,5 @@
package net.engio.mbassy.error; package net.engio.mbassy.error;
import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
/** /**
@ -20,7 +19,7 @@ public class PublicationError {
// Internal state // Internal state
private Throwable cause; private Throwable cause;
private String message; private String message;
private Method handler; private String methodName;
private Object listener; private Object listener;
private Object[] publishedObjects; private Object[] publishedObjects;
@ -59,12 +58,12 @@ public class PublicationError {
return this; return this;
} }
public Method getHandler() { public String getMethodName() {
return this.handler; return this.methodName;
} }
public PublicationError setHandler(Method handler) { public PublicationError setMethodName(String methodName) {
this.handler = handler; this.methodName = methodName;
return this; return this;
} }
@ -122,7 +121,7 @@ public class PublicationError {
newLine + newLine +
"\tmessage='" + this.message + '\'' + "\tmessage='" + this.message + '\'' +
newLine + newLine +
"\thandler=" + this.handler + "\tmethod=" + this.methodName +
newLine + newLine +
"\tlistener=" + this.listener + "\tlistener=" + this.listener +
newLine + newLine +

View File

@ -1,6 +1,5 @@
package net.engio.mbassy.listener; package net.engio.mbassy.listener;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
@ -8,6 +7,8 @@ import net.engio.mbassy.annotations.Handler;
import net.engio.mbassy.annotations.Synchronized; import net.engio.mbassy.annotations.Synchronized;
import net.engio.mbassy.common.ReflectionUtils; import net.engio.mbassy.common.ReflectionUtils;
import com.esotericsoftware.reflectasm.MethodAccess;
/** /**
* Any method in any class annotated with the @Handler annotation represents a message handler. The class that contains * Any method in any class annotated with the @Handler annotation represents a message handler. The class that contains
* the handler is called a message listener and more generally, any class containing a message handler in its class hierarchy * the handler is called a message listener and more generally, any class containing a message handler in its class hierarchy
@ -29,7 +30,8 @@ import net.engio.mbassy.common.ReflectionUtils;
*/ */
public class MessageHandler { public class MessageHandler {
private final Method handler; private final MethodAccess handler;
private final int methodIndex;
private final Class<?>[] handledMessages; private final Class<?>[] handledMessages;
private final boolean acceptsSubtypes; private final boolean acceptsSubtypes;
private final MessageListener listenerConfig; private final MessageListener listenerConfig;
@ -46,9 +48,10 @@ public class MessageHandler {
} }
Class<?>[] handledMessages = handler.getParameterTypes(); Class<?>[] handledMessages = handler.getParameterTypes();
handler.setAccessible(true);
this.handler = handler; this.handler = MethodAccess.get(handler.getDeclaringClass());
this.methodIndex = this.handler.getIndex(handler.getName(), handledMessages);
this.acceptsSubtypes = !handlerConfig.rejectSubtypes(); this.acceptsSubtypes = !handlerConfig.rejectSubtypes();
this.listenerConfig = listenerMetadata; this.listenerConfig = listenerMetadata;
this.isSynchronized = ReflectionUtils.getAnnotation(handler, Synchronized.class) != null; this.isSynchronized = ReflectionUtils.getAnnotation(handler, Synchronized.class) != null;
@ -59,10 +62,6 @@ public class MessageHandler {
this.isVarArg = handledMessages.length == 1 && handledMessages[0].isArray(); this.isVarArg = handledMessages.length == 1 && handledMessages[0].isArray();
} }
public <A extends Annotation> A getAnnotation(Class<A> annotationType){
return ReflectionUtils.getAnnotation(this.handler,annotationType);
}
public boolean isSynchronized(){ public boolean isSynchronized(){
return this.isSynchronized; return this.isSynchronized;
} }
@ -71,10 +70,14 @@ public class MessageHandler {
return this.listenerConfig.isFromListener(listener); return this.listenerConfig.isFromListener(listener);
} }
public Method getHandler() { public MethodAccess getHandler() {
return this.handler; return this.handler;
} }
public int getMethodIndex() {
return this.methodIndex;
}
public Class<?>[] getHandledMessages() { public Class<?>[] getHandledMessages() {
return this.handledMessages; return this.handledMessages;
} }

View File

@ -1,7 +1,6 @@
package net.engio.mbassy.subscription; package net.engio.mbassy.subscription;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
import net.engio.mbassy.common.IConcurrentSet; import net.engio.mbassy.common.IConcurrentSet;
@ -13,6 +12,8 @@ import net.engio.mbassy.error.ErrorHandlingSupport;
import net.engio.mbassy.error.PublicationError; import net.engio.mbassy.error.PublicationError;
import net.engio.mbassy.listener.MessageHandler; import net.engio.mbassy.listener.MessageHandler;
import com.esotericsoftware.reflectasm.MethodAccess;
/** /**
* A subscription is a thread-safe container that manages exactly one message handler of all registered * A subscription is a thread-safe container that manages exactly one message handler of all registered
* message listeners of the same class, i.e. all subscribed instances (excluding subclasses) of a SingleMessageHandler.class * message listeners of the same class, i.e. all subscribed instances (excluding subclasses) of a SingleMessageHandler.class
@ -126,27 +127,18 @@ public class Subscription {
public void publishToSubscription(ErrorHandlingSupport errorHandler, Object message) { public void publishToSubscription(ErrorHandlingSupport errorHandler, Object message) {
if (this.listeners.size() > 0) { if (this.listeners.size() > 0) {
MethodAccess handler = this.handlerMetadata.getHandler();
/** int methodIndex = this.handlerMetadata.getMethodIndex();
* Delivers the given message to the given set of listeners.
* Delivery may be delayed, aborted or restricted in various ways, depending
* on the configuration of the dispatcher
*
* @param publication The message publication that initiated the dispatch
* @param message The message that should be delivered to the listeners
* @param listeners The listeners that should receive the message
*/
Method handler = this.handlerMetadata.getHandler();
for (Object listener : this.listeners) { for (Object listener : this.listeners) {
try { try {
this.invocation.invoke(listener, handler, message); this.invocation.invoke(listener, handler, methodIndex, message);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
errorHandler.handlePublicationError(new PublicationError() errorHandler.handlePublicationError(new PublicationError()
.setMessage("Error during invocation of message handler. " + .setMessage("Error during invocation of message handler. " +
"The class or method is not accessible") "The class or method is not accessible")
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(message)); .setPublishedObject(message));
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@ -155,7 +147,7 @@ public class Subscription {
"Wrong arguments passed to method. Was: " + message.getClass() "Wrong arguments passed to method. Was: " + message.getClass()
+ "Expected: " + handler.getParameterTypes()[0]) + "Expected: " + handler.getParameterTypes()[0])
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(message)); .setPublishedObject(message));
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
@ -163,7 +155,7 @@ public class Subscription {
.setMessage("Error during invocation of message handler. " + .setMessage("Error during invocation of message handler. " +
"Message handler threw exception") "Message handler threw exception")
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(message)); .setPublishedObject(message));
} catch (Throwable e) { } catch (Throwable e) {
@ -171,7 +163,7 @@ public class Subscription {
.setMessage("Error during invocation of message handler. " + .setMessage("Error during invocation of message handler. " +
"The handler code threw an exception") "The handler code threw an exception")
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(message)); .setPublishedObject(message));
} }
@ -181,27 +173,18 @@ public class Subscription {
public void publishToSubscription(ErrorHandlingSupport errorHandler, Object message1, Object message2) { public void publishToSubscription(ErrorHandlingSupport errorHandler, Object message1, Object message2) {
if (this.listeners.size() > 0) { if (this.listeners.size() > 0) {
MethodAccess handler = this.handlerMetadata.getHandler();
/** int methodIndex = this.handlerMetadata.getMethodIndex();
* Delivers the given message to the given set of listeners.
* Delivery may be delayed, aborted or restricted in various ways, depending
* on the configuration of the dispatcher
*
* @param publication The message publication that initiated the dispatch
* @param message The message that should be delivered to the listeners
* @param listeners The listeners that should receive the message
*/
Method handler = this.handlerMetadata.getHandler();
for (Object listener : this.listeners) { for (Object listener : this.listeners) {
try { try {
this.invocation.invoke(listener, handler, message1, message2); this.invocation.invoke(listener, handler, methodIndex, message1, message2);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
errorHandler.handlePublicationError(new PublicationError() errorHandler.handlePublicationError(new PublicationError()
.setMessage("Error during invocation of message handler. " + .setMessage("Error during invocation of message handler. " +
"The class or method is not accessible") "The class or method is not accessible")
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(message1, message2)); .setPublishedObject(message1, message2));
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@ -214,7 +197,7 @@ public class Subscription {
handler.getParameterTypes()[1] handler.getParameterTypes()[1]
) )
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(message1, message2)); .setPublishedObject(message1, message2));
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
@ -222,7 +205,7 @@ public class Subscription {
.setMessage("Error during invocation of message handler. " + .setMessage("Error during invocation of message handler. " +
"Message handler threw exception") "Message handler threw exception")
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(message1, message2)); .setPublishedObject(message1, message2));
} catch (Throwable e) { } catch (Throwable e) {
@ -230,7 +213,7 @@ public class Subscription {
.setMessage("Error during invocation of message handler. " + .setMessage("Error during invocation of message handler. " +
"The handler code threw an exception") "The handler code threw an exception")
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(message1, message2)); .setPublishedObject(message1, message2));
} }
@ -240,60 +223,51 @@ public class Subscription {
public void publishToSubscription(ErrorHandlingSupport errorHandler, Object message1, Object message2, Object message3) { public void publishToSubscription(ErrorHandlingSupport errorHandler, Object message1, Object message2, Object message3) {
if (this.listeners.size() > 0) { if (this.listeners.size() > 0) {
MethodAccess handler = this.handlerMetadata.getHandler();
/** int methodIndex = this.handlerMetadata.getMethodIndex();
* Delivers the given message to the given set of listeners.
* Delivery may be delayed, aborted or restricted in various ways, depending
* on the configuration of the dispatcher
*
* @param publication The message publication that initiated the dispatch
* @param message The message that should be delivered to the listeners
* @param listeners The listeners that should receive the message
*/
Method handler = this.handlerMetadata.getHandler();
for (Object listener : this.listeners) { for (Object listener : this.listeners) {
try { try {
this.invocation.invoke(listener, handler, message1, message2, message3); this.invocation.invoke(listener, handler, methodIndex, message1, message2, message3);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
errorHandler.handlePublicationError(new PublicationError() errorHandler.handlePublicationError(new PublicationError()
.setMessage("Error during invocation of message handler. " + .setMessage("Error during invocation of message handler. " +
"The class or method is not accessible") "The class or method is not accessible")
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(message1, message2, message3)); .setPublishedObject(message1, message2, message3));
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
errorHandler.handlePublicationError(new PublicationError() errorHandler.handlePublicationError(new PublicationError()
.setMessage("Error during invocation of message handler. " + .setMessage("Error during invocation of message handler. " +
"Wrong arguments passed to method. Was: " + "Wrong arguments passed to method. Was: " +
message1.getClass() + ", " + message1.getClass() + ", " +
message2.getClass() + ", " + message2.getClass() + ", " +
message3.getClass() message3.getClass()
+ ". Expected: " + handler.getParameterTypes()[0] + ", " + + ". Expected: " + handler.getParameterTypes()[0] + ", " +
handler.getParameterTypes()[1] + ", " + handler.getParameterTypes()[1] + ", " +
handler.getParameterTypes()[2] handler.getParameterTypes()[2]
) )
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(message1, message2, message3)); .setPublishedObject(message1, message2, message3));
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
errorHandler.handlePublicationError(new PublicationError() errorHandler.handlePublicationError(new PublicationError()
.setMessage("Error during invocation of message handler. " + .setMessage("Error during invocation of message handler. " +
"Message handler threw exception") "Message handler threw exception")
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(message1, message2, message3)); .setPublishedObject(message1, message2, message3));
} catch (Throwable e) { } catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError() errorHandler.handlePublicationError(new PublicationError()
.setMessage("Error during invocation of message handler. " + .setMessage("Error during invocation of message handler. " +
"The handler code threw an exception") "The handler code threw an exception")
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(message1, message2, message3)); .setPublishedObject(message1, message2, message3));
} }
} }
} }
@ -301,54 +275,45 @@ public class Subscription {
public void publishToSubscription(ErrorHandlingSupport errorHandler, Object... messages) { public void publishToSubscription(ErrorHandlingSupport errorHandler, Object... messages) {
if (this.listeners.size() > 0) { if (this.listeners.size() > 0) {
MethodAccess handler = this.handlerMetadata.getHandler();
/** int methodIndex = this.handlerMetadata.getMethodIndex();
* Delivers the given message to the given set of listeners.
* Delivery may be delayed, aborted or restricted in various ways, depending
* on the configuration of the dispatcher
*
* @param publication The message publication that initiated the dispatch
* @param message The message that should be delivered to the listeners
* @param listeners The listeners that should receive the message
*/
Method handler = this.handlerMetadata.getHandler();
for (Object listener : this.listeners) { for (Object listener : this.listeners) {
try { try {
this.invocation.invoke(listener, handler, messages); this.invocation.invoke(listener, handler, methodIndex, messages);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
errorHandler.handlePublicationError(new PublicationError() errorHandler.handlePublicationError(new PublicationError()
.setMessage("Error during invocation of message handler. " + .setMessage("Error during invocation of message handler. " +
"The class or method is not accessible") "The class or method is not accessible")
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(messages)); .setPublishedObject(messages));
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
errorHandler.handlePublicationError(new PublicationError() errorHandler.handlePublicationError(new PublicationError()
.setMessage("Error during invocation of message handler. " + .setMessage("Error during invocation of message handler. " +
"Wrong arguments passed to method. Was: " + Arrays.deepToString(messages) "Wrong arguments passed to method. Was: " + Arrays.deepToString(messages)
+ "Expected: " + Arrays.deepToString(handler.getParameterTypes())) + "Expected: " + Arrays.deepToString(handler.getParameterTypes()))
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(messages)); .setPublishedObject(messages));
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
errorHandler.handlePublicationError(new PublicationError() errorHandler.handlePublicationError(new PublicationError()
.setMessage("Error during invocation of message handler. " + .setMessage("Error during invocation of message handler. " +
"Message handler threw exception") "Message handler threw exception")
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(messages)); .setPublishedObject(messages));
} catch (Throwable e) { } catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError() errorHandler.handlePublicationError(new PublicationError()
.setMessage("Error during invocation of message handler. " + .setMessage("Error during invocation of message handler. " +
"The handler code threw an exception") "The handler code threw an exception")
.setCause(e) .setCause(e)
.setHandler(handler) .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener) .setListener(listener)
.setPublishedObject(messages)); .setPublishedObject(messages));
} }
} }
} }