I've run into a RMI classloading problem that I don't know how to
solve and I'm hoping someone has a suggestion about how to proceed.
In this scenario there are 3 jvms:
A. gshell
B. a controller server
C. a cluster node.
In B, there are 2 classloaders of interest: j2ee-security and plugin-
farm. The class I'm having trouble with is DownloadResults, which is
available in plugin-farm but not j2ee-security.
On B, there's a gbean, FarmGBean, in plugin-farm that calls the
PluginInstallerGBean on C and gets a DownloadResults back. This call
is over jmx using rmi.
This call is made under two circumstances:
1. FarmGBean on B recieves a multicast packet from C and calls back to
C, and successfully gets the DownloadResults back. I'm assuming that
rmi is using the plugin-farm classloader here for the
ObjectInputStream but haven't figure out how to check.
2. Gshell on A can call over jmx/rmi to the FarmGBean on B resulting
in a call to C. In this case DownloadResults cannot be loaded: I get
a message saying its not available in the j2ee-security classloader.
(stack trace at end of email).
I think that in (1) the thread that dispatches the call to C was
started in code loaded in the plugin-farm classloader whereas in (2)
the thread was started in the j2ee-server classloader. I'm not
certain of this however.
I've tried two things that haven't worked:
a. setting the thread context classloader before the call to C to the
plugin-farm classloader
b. making the call to C a PrivilegedExceptionAction
An idea I've had that I haven't tried yet because it seems rather
complicated and seems like it might introduce security holes (at least
it needs more thought) would be to modify the RMIClassLoaderSpiImpl.
My idea is to represent geronimo classloaders with urls containing
their artifactIds. The server would include this more or less fake
url in the codebase for a class and the client would look for this
special url to try to load the class with.
Anyone know what osgi does for similar situations? Anyone have any
suggestions?
many thanks
david jencks
Here's the stack trace (on B):
12:22:05,777 WARN [FarmGBean] Error attempting to distribute plugin
[EMAIL PROTECTED] to node
0.0.0.0:1109
java.rmi.UnmarshalException: error unmarshalling return; nested
exception is:
java.lang.ClassNotFoundException:
org.apache.geronimo.system.plugin.DownloadResults in classloader
org.apache.geronimo.framework/j2ee-security/2.2-SNAPSHOT/car (no
security manager: RMI class loader disabled)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:162)
at com.sun.jmx.remote.internal.PRef.invoke(Unknown Source)
at javax.management.remote.rmi.RMIConnectionImpl_Stub.invoke(Unknown
Source)
at javax.management.remote.rmi.RMIConnector
$RemoteMBeanServerConnection.invoke(RMIConnector.java:972)
at
org
.apache
.geronimo.system.jmx.KernelDelegate.invokeKernel(KernelDelegate.java:
886)
at
org
.apache.geronimo.system.jmx.KernelDelegate.invoke(KernelDelegate.java:
547)
at
org
.apache
.geronimo
.kernel
.basic.KernelOperationInvoker.invoke(KernelOperationInvoker.java:46)
at
org
.apache
.geronimo
.system
.jmx
.JMXProxyMethodInterceptor.intercept(JMXProxyMethodInterceptor.java:89)
at org.apache.geronimo.system.plugin.PluginInstaller$$EnhancerByCGLIB$
$80823d3e.install(<generated>)
at
org.apache.geronimo.farm.plugin.FarmGBean.installToNode(FarmGBean.java:
223)
at
org
.apache.geronimo.farm.plugin.FarmGBean.installToCluster(FarmGBean.java:
207)
at
org
.apache
.geronimo.farm.plugin.FarmGBean.installToClusters(FarmGBean.java:199)
at
org
.apache
.geronimo.farm.plugin.FarmGBean.addPluginToCluster(FarmGBean.java:193)
at
org
.apache
.geronimo.farm.plugin.FarmGBean.addPluginToCluster(FarmGBean.java:181)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun
.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun
.reflect
.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:585)
at
org
.apache
.geronimo
.gbean
.runtime.ReflectionMethodInvoker.invoke(ReflectionMethodInvoker.java:34)
at
org
.apache
.geronimo.gbean.runtime.GBeanOperation.invoke(GBeanOperation.java:130)
at
org
.apache.geronimo.gbean.runtime.GBeanInstance.invoke(GBeanInstance.java:
850)
at
org.apache.geronimo.kernel.basic.BasicKernel.invoke(BasicKernel.java:
237)
at org.apache.geronimo.kernel.KernelGBean.invoke(KernelGBean.java:342)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun
.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun
.reflect
.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:585)
at
org
.apache
.geronimo
.gbean
.runtime.ReflectionMethodInvoker.invoke(ReflectionMethodInvoker.java:34)
at
org
.apache
.geronimo.gbean.runtime.GBeanOperation.invoke(GBeanOperation.java:130)
at
org
.apache.geronimo.gbean.runtime.GBeanInstance.invoke(GBeanInstance.java:
850)
at
org.apache.geronimo.kernel.basic.BasicKernel.invoke(BasicKernel.java:
237)
at
org
.apache
.geronimo.system.jmx.MBeanGBeanBridge.invoke(MBeanGBeanBridge.java:172)
at
com
.sun
.jmx.mbeanserver.DynamicMetaDataImpl.invoke(DynamicMetaDataImpl.java:
213)
at com.sun.jmx.mbeanserver.MetaDataImpl.invoke(MetaDataImpl.java:220)
at
com
.sun
.jmx
.interceptor
.DefaultMBeanServerInterceptor
.invoke(DefaultMBeanServerInterceptor.java:815)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:
784)
at
javax
.management
.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1410)
at javax.management.remote.rmi.RMIConnectionImpl.access
$100(RMIConnectionImpl.java:81)
at javax.management.remote.rmi.RMIConnectionImpl
$PrivilegedOperation.run(RMIConnectionImpl.java:1247)
at java.security.AccessController.doPrivileged(Native Method)
at
javax
.management
.remote
.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:
1350)
at
javax
.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:
784)
at sun.reflect.GeneratedMethodAccessor57.invoke(Unknown Source)
at
sun
.reflect
.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:585)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:294)
at sun.rmi.transport.Transport$1.run(Transport.java:153)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
at
sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:466)
at sun.rmi.transport.tcp.TCPTransport
$ConnectionHandler.run(TCPTransport.java:707)
at java.lang.Thread.run(Thread.java:613)
Caused by: java.lang.ClassNotFoundException:
org.apache.geronimo.system.plugin.DownloadResults in classloader
org.apache.geronimo.framework/j2ee-security/2.2-SNAPSHOT/car (no
security manager: RMI class loader disabled)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:371)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:165)
at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:620)
at
org
.apache
.geronimo
.kernel.rmi.RMIClassLoaderSpiImpl.loadClass(RMIClassLoaderSpiImpl.java:
53)
at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:247)
at
sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:
197)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:
1544)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1466)
at
java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:
1699)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:290)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:139)
... 51 more