diff --git a/src/main/java/net/engio/mbassy/dispatch/IHandlerInvocation.java b/src/main/java/net/engio/mbassy/dispatch/IHandlerInvocation.java
index dbae72f..415d0a2 100644
--- a/src/main/java/net/engio/mbassy/dispatch/IHandlerInvocation.java
+++ b/src/main/java/net/engio/mbassy/dispatch/IHandlerInvocation.java
@@ -1,6 +1,6 @@
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
@@ -28,7 +28,7 @@ public interface IHandlerInvocation {
* type that the handler consumes
* @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
@@ -39,7 +39,7 @@ public interface IHandlerInvocation {
* type that the handler consumes
* @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
@@ -50,7 +50,7 @@ public interface IHandlerInvocation {
* type that the handler consumes
* @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
@@ -61,5 +61,5 @@ public interface IHandlerInvocation {
* type that the handler consumes
* @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;
}
diff --git a/src/main/java/net/engio/mbassy/dispatch/ReflectiveHandlerInvocation.java b/src/main/java/net/engio/mbassy/dispatch/ReflectiveHandlerInvocation.java
index 07d0bb2..b65dd21 100644
--- a/src/main/java/net/engio/mbassy/dispatch/ReflectiveHandlerInvocation.java
+++ b/src/main/java/net/engio/mbassy/dispatch/ReflectiveHandlerInvocation.java
@@ -1,6 +1,6 @@
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.
@@ -17,22 +17,22 @@ public class ReflectiveHandlerInvocation implements IHandlerInvocation {
}
@Override
- public void invoke(final Object listener, Method handler, final Object message) throws Throwable {
- handler.invoke(listener, message);
+ public void invoke(final Object listener, final MethodAccess handler, final int methodIndex, final Object message) throws Throwable {
+ handler.invoke(listener, methodIndex, message);
}
@Override
- public void invoke(final Object listener, Method handler, final Object message1, final Object message2) throws Throwable {
- handler.invoke(listener, message1, message2);
+ public void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object message1, final Object message2) throws Throwable {
+ handler.invoke(listener, methodIndex, message1, message2);
}
@Override
- public void invoke(final Object listener, Method handler, final Object message1, final Object message2, final Object message3) throws Throwable {
- handler.invoke(listener, message1, message2, message3);
+ public void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object message1, final Object message2, final Object message3) throws Throwable {
+ handler.invoke(listener, methodIndex, message1, message2, message3);
}
@Override
- public void invoke(final Object listener, Method handler, final Object... messages) throws Throwable {
- handler.invoke(listener, messages);
+ public void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object... messages) throws Throwable {
+ handler.invoke(listener, methodIndex, messages);
}
}
diff --git a/src/main/java/net/engio/mbassy/dispatch/SynchronizedHandlerInvocation.java b/src/main/java/net/engio/mbassy/dispatch/SynchronizedHandlerInvocation.java
index b0859d5..af6ed34 100644
--- a/src/main/java/net/engio/mbassy/dispatch/SynchronizedHandlerInvocation.java
+++ b/src/main/java/net/engio/mbassy/dispatch/SynchronizedHandlerInvocation.java
@@ -1,6 +1,6 @@
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
@@ -19,30 +19,30 @@ public class SynchronizedHandlerInvocation implements IHandlerInvocation {
}
@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) {
- this.delegate.invoke(listener, handler, message);
+ this.delegate.invoke(listener, handler, methodIndex, message);
}
}
@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) {
- this.delegate.invoke(listener, handler, message1, message2);
+ this.delegate.invoke(listener, handler, methodIndex, message1, message2);
}
}
@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) {
- this.delegate.invoke(listener, handler, message1, message2, message3);
+ this.delegate.invoke(listener, handler, methodIndex, message1, message2, message3);
}
}
@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) {
- this.delegate.invoke(listener, handler, messages);
+ this.delegate.invoke(listener, handler, methodIndex, messages);
}
}
}
diff --git a/src/main/java/net/engio/mbassy/error/PublicationError.java b/src/main/java/net/engio/mbassy/error/PublicationError.java
index 7765896..5bdb551 100644
--- a/src/main/java/net/engio/mbassy/error/PublicationError.java
+++ b/src/main/java/net/engio/mbassy/error/PublicationError.java
@@ -1,6 +1,5 @@
package net.engio.mbassy.error;
-import java.lang.reflect.Method;
import java.util.Arrays;
/**
@@ -20,7 +19,7 @@ public class PublicationError {
// Internal state
private Throwable cause;
private String message;
- private Method handler;
+ private String methodName;
private Object listener;
private Object[] publishedObjects;
@@ -59,12 +58,12 @@ public class PublicationError {
return this;
}
- public Method getHandler() {
- return this.handler;
+ public String getMethodName() {
+ return this.methodName;
}
- public PublicationError setHandler(Method handler) {
- this.handler = handler;
+ public PublicationError setMethodName(String methodName) {
+ this.methodName = methodName;
return this;
}
@@ -122,7 +121,7 @@ public class PublicationError {
newLine +
"\tmessage='" + this.message + '\'' +
newLine +
- "\thandler=" + this.handler +
+ "\tmethod=" + this.methodName +
newLine +
"\tlistener=" + this.listener +
newLine +
diff --git a/src/main/java/net/engio/mbassy/listener/MessageHandler.java b/src/main/java/net/engio/mbassy/listener/MessageHandler.java
index dbe4af3..219273a 100644
--- a/src/main/java/net/engio/mbassy/listener/MessageHandler.java
+++ b/src/main/java/net/engio/mbassy/listener/MessageHandler.java
@@ -1,6 +1,5 @@
package net.engio.mbassy.listener;
-import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
@@ -8,6 +7,8 @@ import net.engio.mbassy.annotations.Handler;
import net.engio.mbassy.annotations.Synchronized;
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
* 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 {
- private final Method handler;
+ private final MethodAccess handler;
+ private final int methodIndex;
private final Class>[] handledMessages;
private final boolean acceptsSubtypes;
private final MessageListener listenerConfig;
@@ -46,9 +48,10 @@ public class MessageHandler {
}
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.listenerConfig = listenerMetadata;
this.isSynchronized = ReflectionUtils.getAnnotation(handler, Synchronized.class) != null;
@@ -59,10 +62,6 @@ public class MessageHandler {
this.isVarArg = handledMessages.length == 1 && handledMessages[0].isArray();
}
- public A getAnnotation(Class annotationType){
- return ReflectionUtils.getAnnotation(this.handler,annotationType);
- }
-
public boolean isSynchronized(){
return this.isSynchronized;
}
@@ -71,10 +70,14 @@ public class MessageHandler {
return this.listenerConfig.isFromListener(listener);
}
- public Method getHandler() {
+ public MethodAccess getHandler() {
return this.handler;
}
+ public int getMethodIndex() {
+ return this.methodIndex;
+ }
+
public Class>[] getHandledMessages() {
return this.handledMessages;
}
diff --git a/src/main/java/net/engio/mbassy/subscription/Subscription.java b/src/main/java/net/engio/mbassy/subscription/Subscription.java
index 06f678c..24f3c13 100644
--- a/src/main/java/net/engio/mbassy/subscription/Subscription.java
+++ b/src/main/java/net/engio/mbassy/subscription/Subscription.java
@@ -1,7 +1,6 @@
package net.engio.mbassy.subscription;
import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.util.Arrays;
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.listener.MessageHandler;
+import com.esotericsoftware.reflectasm.MethodAccess;
+
/**
* 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
@@ -126,27 +127,18 @@ public class Subscription {
public void publishToSubscription(ErrorHandlingSupport errorHandler, Object message) {
if (this.listeners.size() > 0) {
-
- /**
- * 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();
+ MethodAccess handler = this.handlerMetadata.getHandler();
+ int methodIndex = this.handlerMetadata.getMethodIndex();
for (Object listener : this.listeners) {
try {
- this.invocation.invoke(listener, handler, message);
+ this.invocation.invoke(listener, handler, methodIndex, message);
} catch (IllegalAccessException e) {
errorHandler.handlePublicationError(new PublicationError()
.setMessage("Error during invocation of message handler. " +
"The class or method is not accessible")
.setCause(e)
- .setHandler(handler)
+ .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener)
.setPublishedObject(message));
} catch (IllegalArgumentException e) {
@@ -155,7 +147,7 @@ public class Subscription {
"Wrong arguments passed to method. Was: " + message.getClass()
+ "Expected: " + handler.getParameterTypes()[0])
.setCause(e)
- .setHandler(handler)
+ .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener)
.setPublishedObject(message));
} catch (InvocationTargetException e) {
@@ -163,7 +155,7 @@ public class Subscription {
.setMessage("Error during invocation of message handler. " +
"Message handler threw exception")
.setCause(e)
- .setHandler(handler)
+ .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener)
.setPublishedObject(message));
} catch (Throwable e) {
@@ -171,7 +163,7 @@ public class Subscription {
.setMessage("Error during invocation of message handler. " +
"The handler code threw an exception")
.setCause(e)
- .setHandler(handler)
+ .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener)
.setPublishedObject(message));
}
@@ -181,27 +173,18 @@ public class Subscription {
public void publishToSubscription(ErrorHandlingSupport errorHandler, Object message1, Object message2) {
if (this.listeners.size() > 0) {
-
- /**
- * 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();
+ MethodAccess handler = this.handlerMetadata.getHandler();
+ int methodIndex = this.handlerMetadata.getMethodIndex();
for (Object listener : this.listeners) {
try {
- this.invocation.invoke(listener, handler, message1, message2);
+ this.invocation.invoke(listener, handler, methodIndex, message1, message2);
} catch (IllegalAccessException e) {
errorHandler.handlePublicationError(new PublicationError()
.setMessage("Error during invocation of message handler. " +
"The class or method is not accessible")
.setCause(e)
- .setHandler(handler)
+ .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener)
.setPublishedObject(message1, message2));
} catch (IllegalArgumentException e) {
@@ -214,7 +197,7 @@ public class Subscription {
handler.getParameterTypes()[1]
)
.setCause(e)
- .setHandler(handler)
+ .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener)
.setPublishedObject(message1, message2));
} catch (InvocationTargetException e) {
@@ -222,7 +205,7 @@ public class Subscription {
.setMessage("Error during invocation of message handler. " +
"Message handler threw exception")
.setCause(e)
- .setHandler(handler)
+ .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener)
.setPublishedObject(message1, message2));
} catch (Throwable e) {
@@ -230,7 +213,7 @@ public class Subscription {
.setMessage("Error during invocation of message handler. " +
"The handler code threw an exception")
.setCause(e)
- .setHandler(handler)
+ .setMethodName(handler.getMethodNames()[methodIndex])
.setListener(listener)
.setPublishedObject(message1, message2));
}
@@ -240,60 +223,51 @@ public class Subscription {
public void publishToSubscription(ErrorHandlingSupport errorHandler, Object message1, Object message2, Object message3) {
if (this.listeners.size() > 0) {
-
- /**
- * 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();
+ MethodAccess handler = this.handlerMetadata.getHandler();
+ int methodIndex = this.handlerMetadata.getMethodIndex();
for (Object listener : this.listeners) {
try {
- this.invocation.invoke(listener, handler, message1, message2, message3);
+ this.invocation.invoke(listener, handler, methodIndex, message1, message2, message3);
} catch (IllegalAccessException e) {
errorHandler.handlePublicationError(new PublicationError()
- .setMessage("Error during invocation of message handler. " +
- "The class or method is not accessible")
- .setCause(e)
- .setHandler(handler)
- .setListener(listener)
- .setPublishedObject(message1, message2, message3));
+ .setMessage("Error during invocation of message handler. " +
+ "The class or method is not accessible")
+ .setCause(e)
+ .setMethodName(handler.getMethodNames()[methodIndex])
+ .setListener(listener)
+ .setPublishedObject(message1, message2, message3));
} catch (IllegalArgumentException e) {
errorHandler.handlePublicationError(new PublicationError()
- .setMessage("Error during invocation of message handler. " +
- "Wrong arguments passed to method. Was: " +
- message1.getClass() + ", " +
- message2.getClass() + ", " +
- message3.getClass()
- + ". Expected: " + handler.getParameterTypes()[0] + ", " +
- handler.getParameterTypes()[1] + ", " +
- handler.getParameterTypes()[2]
- )
- .setCause(e)
- .setHandler(handler)
- .setListener(listener)
- .setPublishedObject(message1, message2, message3));
+ .setMessage("Error during invocation of message handler. " +
+ "Wrong arguments passed to method. Was: " +
+ message1.getClass() + ", " +
+ message2.getClass() + ", " +
+ message3.getClass()
+ + ". Expected: " + handler.getParameterTypes()[0] + ", " +
+ handler.getParameterTypes()[1] + ", " +
+ handler.getParameterTypes()[2]
+ )
+ .setCause(e)
+ .setMethodName(handler.getMethodNames()[methodIndex])
+ .setListener(listener)
+ .setPublishedObject(message1, message2, message3));
} catch (InvocationTargetException e) {
errorHandler.handlePublicationError(new PublicationError()
- .setMessage("Error during invocation of message handler. " +
- "Message handler threw exception")
- .setCause(e)
- .setHandler(handler)
- .setListener(listener)
- .setPublishedObject(message1, message2, message3));
+ .setMessage("Error during invocation of message handler. " +
+ "Message handler threw exception")
+ .setCause(e)
+ .setMethodName(handler.getMethodNames()[methodIndex])
+ .setListener(listener)
+ .setPublishedObject(message1, message2, message3));
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError()
- .setMessage("Error during invocation of message handler. " +
- "The handler code threw an exception")
- .setCause(e)
- .setHandler(handler)
- .setListener(listener)
- .setPublishedObject(message1, message2, message3));
+ .setMessage("Error during invocation of message handler. " +
+ "The handler code threw an exception")
+ .setCause(e)
+ .setMethodName(handler.getMethodNames()[methodIndex])
+ .setListener(listener)
+ .setPublishedObject(message1, message2, message3));
}
}
}
@@ -301,54 +275,45 @@ public class Subscription {
public void publishToSubscription(ErrorHandlingSupport errorHandler, Object... messages) {
if (this.listeners.size() > 0) {
-
- /**
- * 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();
+ MethodAccess handler = this.handlerMetadata.getHandler();
+ int methodIndex = this.handlerMetadata.getMethodIndex();
for (Object listener : this.listeners) {
try {
- this.invocation.invoke(listener, handler, messages);
+ this.invocation.invoke(listener, handler, methodIndex, messages);
} catch (IllegalAccessException e) {
errorHandler.handlePublicationError(new PublicationError()
- .setMessage("Error during invocation of message handler. " +
- "The class or method is not accessible")
- .setCause(e)
- .setHandler(handler)
- .setListener(listener)
- .setPublishedObject(messages));
+ .setMessage("Error during invocation of message handler. " +
+ "The class or method is not accessible")
+ .setCause(e)
+ .setMethodName(handler.getMethodNames()[methodIndex])
+ .setListener(listener)
+ .setPublishedObject(messages));
} catch (IllegalArgumentException e) {
errorHandler.handlePublicationError(new PublicationError()
- .setMessage("Error during invocation of message handler. " +
- "Wrong arguments passed to method. Was: " + Arrays.deepToString(messages)
- + "Expected: " + Arrays.deepToString(handler.getParameterTypes()))
- .setCause(e)
- .setHandler(handler)
- .setListener(listener)
- .setPublishedObject(messages));
+ .setMessage("Error during invocation of message handler. " +
+ "Wrong arguments passed to method. Was: " + Arrays.deepToString(messages)
+ + "Expected: " + Arrays.deepToString(handler.getParameterTypes()))
+ .setCause(e)
+ .setMethodName(handler.getMethodNames()[methodIndex])
+ .setListener(listener)
+ .setPublishedObject(messages));
} catch (InvocationTargetException e) {
errorHandler.handlePublicationError(new PublicationError()
- .setMessage("Error during invocation of message handler. " +
- "Message handler threw exception")
- .setCause(e)
- .setHandler(handler)
- .setListener(listener)
- .setPublishedObject(messages));
+ .setMessage("Error during invocation of message handler. " +
+ "Message handler threw exception")
+ .setCause(e)
+ .setMethodName(handler.getMethodNames()[methodIndex])
+ .setListener(listener)
+ .setPublishedObject(messages));
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError()
- .setMessage("Error during invocation of message handler. " +
- "The handler code threw an exception")
- .setCause(e)
- .setHandler(handler)
- .setListener(listener)
- .setPublishedObject(messages));
+ .setMessage("Error during invocation of message handler. " +
+ "The handler code threw an exception")
+ .setCause(e)
+ .setMethodName(handler.getMethodNames()[methodIndex])
+ .setListener(listener)
+ .setPublishedObject(messages));
}
}
}