You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@geronimo.apache.org by David Jencks <da...@yahoo.com> on 2008/10/03 09:08:32 UTC

RMI Classloading problem.... help appreciated.

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  
listorg.apache.geronimo.farm.plugin.JpaPluginList@6828c5 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
  

Re: RMI Classloading problem.... help appreciated.

Posted by Rick McGuire <ri...@gmail.com>.
David,

No answers for you at this point, but I think the first thing I'd do is 
verify which thread context classloader is set in the case that's 
working.  Perhaps the problem is not in setting the thread context 
loader, but rather getting it set to the correct one.  Are the calls to 
C occurring in the same place in the FarmBean code?  If not, are there 
any fundamental differences between the call environments?

Rick

David Jencks wrote:
> 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 
> listorg.apache.geronimo.farm.plugin.JpaPluginList@6828c5 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
>  
>