-
Bug
-
Resolution: Obsolete
-
Major
-
JBossAS-5.1.0.GA
I listen for the Notifications (JMX.mbean.registered, JMX.mbean.unregistered) of the MBeanServer "JMImplementation:type=MBeanServerDelegate".
I want to do that inside the JBoss VM and also from a different VM (e.g. a JUnit Test case).
I add a RMINotificationListener via the RMIAdaptor.
If i do it within the JBoss VM everything is fine and works OK.
If i do it from a different VM the RMINotificationListener class can't be found.
org.jboss.invocation.JBossLazyUnmarshallingException: getArguments failed
at org.jboss.invocation.MarshalledInvocation.getArguments(MarshalledInvocation.java:513)
at org.jboss.jmx.connector.invoker.InvokerAdaptorService.invoke(InvokerAdaptorService.java:233)
Caused by: java.lang.ClassNotFoundException: org.jboss.jmx.adaptor.rmi.RMINotificationListener
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at org.jboss.invocation.MarshalledValueInputStream.resolveProxyClass(MarshalledValueInputStream.java:159)
at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1531)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1493)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1667)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1323)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at org.jboss.invocation.MarshalledValue.get(MarshalledValue.java:91)
at org.jboss.invocation.MarshalledInvocation.getArguments(MarshalledInvocation.java:509)
The reason is:
In case of calling addNotificationListener() from a different VM the invocation is a MarshalledInvocation.
In the invoke() method of the org.jboss.jmx.connector.invoker.InvokerAdaptorService there is a call to
Object[] args = invocation.getArguments();
In the getArguments() it comes to the unmarshalling of the arguments (one is the RMINotificationListener).
Therefore it is tried to load the argument classes via the Thread's contextClassLoader.
In the InvokerAdaptorService few statements before the getArguments() call there is a call to
getClassLoaderFor(ObjectName name) of the MBeanServerImpl
// Obtain the ClassLoader associated with the MBean deployment
newCL = server.getClassLoaderFor(objectName);
The InvokerAdaptorService then sets the Thread's contextClassLoader.
if (newCL != null && newCL != oldCL)
SecurityActions.setContextClassLoader(newCL);
In the method getClassLoaderFor() the SystemClassLoader is returned for the "JMImplementation:type=MBeanServerDelegate".
public ClassLoader getClassLoaderFor(ObjectName name)
throws InstanceNotFoundException
The SystemClassLoader didn't the see RMINotificationListener.
Possible solution:
If null or the Thread's contextClassLoader would be returned instead of the SystemClassLoader then the InvokerAdaptorService
didn't modify the Thread's contextClassLoader and the RMINotificationListener is found (and it works OK).