[jboss-user] [EJB/JBoss] - Re: RMI Dynamic Classloading

dubacher do-not-reply at jboss.com
Mon Jul 14 04:54:26 EDT 2008


Hi there.

Unfortunately nobody replied to my initial post. With this post I would like to precise my initial post, hoping that somebody can help me:

My setup:
I have a JBoss (version 4.2.2) to which a war-file is deployed. The war-file contains a ServletContextListener which registers a ServerAccessService class in JNDI on startup. The ServerAccessService class extends from UnicastRemoteObject. So methods defined on ServerAccessService are accessible via RMI from remote clients. So far so good...

What do I want to do?
Let's assume ServerAccessService provides a method "public Foo getFoo (int id)". This method will return an instance of FooImpl which implements Foo. On the remote client I would like to deploy the Foo interface only (and not the class FooImpl). As RMI provides the feature of dynamic class loading it should be possible that FooImpl is loaded from the server as soon as an instance of FooImpl is transmitted to the client. So to wrap it up: When the remote client calls "getFoo(..)" it will get an instance of "FooImpl" which class should be dynamically loaded from the server.

The problem:
It doesn't work out!!! The configuration of the WebService in JBoss is as far as I know correct. WebService is running on port 8083; I  also tried to load the class with the tomcat server running on 8080; the system property java.rmi.server.codebase is set etc.

So now to my investigations:
When the FooImpl class is transmitted to the client, a codebase property is sent along with the instance (The codebase is finally used on the client as a hint where to load the class from). But different from the classes like ArrayList etc. the codebase of FooImpl is not something like "http://myserver:8083" or "http://myserver:8080" but something like "file:/..............". So why that? The reason are ClassLoaders... obviously. When annotating the instances transmitted back to the client with the codebase, something like the following stack trace shows is executed:

Daemon System Thread [RMI TCP Connection(6)-10.130.202.179] (Suspended)      LoaderHandler.getClassAnnotation(Class) 
line: 174      RMIClassLoader$2.getClassAnnotation(Class<?>) 
line: 639      JBossRMIClassLoader.getClassAnnotation(Class) line: 112      RMIClassLoader.getClassAnnotation(Class<?>) 
line: 364      ConnectionOutputStream(MarshalOutputStream).annotateClass(Class<?>) 
line: 75      ConnectionOutputStream(ObjectOutputStream).writeNonProxyDesc(ObjectStreamClass, boolean) 
line: 1250      ConnectionOutputStream(ObjectOutputStream).writeClassDesc(ObjectStreamClass, boolean) 
line: 1203      ConnectionOutputStream(ObjectOutputStream).writeOrdinaryObject(Object, ObjectStreamClass, boolean) 
line: 1387      ConnectionOutputStream(ObjectOutputStream).writeObject0(Object, boolean) 
line: 1150      ConnectionOutputStream(ObjectOutputStream).writeObject(Object) 
line: 326      UnicastRef.marshalValue(Class<?>, Object, ObjectOutput) line: 274      UnicastServerRef.dispatch(Remote, RemoteCall) 
line: 315      ........


Ok. So far so "good". Classes like ArrayList are loaded initially loaded by "SystemClassLoaders" but the class FooImpl is loaded by theWebAppClassLoader (yes you are the author of this class :-)). In the class LoaderHandler the "SystemClassLoader" are registered to return the defined codebase (i.e. the one defined with java.rmi.server.codebase) when the method getClassAnnotation is called. The WebAppClassLoader however doesn't belong to this list. That's why the LoaderHandler will return as codebase the URLs returned by the method WebAppClassLoader(URLClassLoader).getURLs. This is obviously something like "file:/...".

So the client gets a instance of FooImpl and its classes codebase is something like "file:/....". Obviously it cannot find the class FooImpl on the local file system as it has not been deployed > ClassNotFoundException is final result.


The question now: How do I solve this problem?
- Do I need to configure my app differently so that the LoaderHandler will return the codebase defined by java.rmi.server.codebase for the WebAppClassLoader as well?
- Is dynamic class loading not intended to be used with applications deployed as war?
- ...? 

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4164171#4164171

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4164171



More information about the jboss-user mailing list