Mantis - Hessian
Viewing Issue Advanced Details
2860 major always 08-21-08 23:40 12-16-09 16:45
jghallen  
ferg  
normal  
closed 3.1.3  
fixed  
none    
none 4.0.3  
0002860: Hessian/Felix OSGi - classloader problem
We use hessian within a OSGi bundle (Apache Felix 1.0.0) to communicate with a backend server.
Felix is running embedded in a Tomcat (5.5.26).

When creating the hessian proxy the current classloader must be supplied in the create() method in order for the service interface to be found. Default is to use the Thread.currentThread().getContextClassLoader() which will not find the service interface. The service interface and all supporting classes are packaged in a jar file in the OSGi bundle.

The problem is that the deserialisation is allways performed using the Thread.currentThread().getContextClassLoader() classloader and not the classloader that was used to create the hessian proxy.
This classloader can not find the classes in the to perform a correct deserialization of the return value, a simple transfer object. Instead of returning ArrayList<TO> it will return a ArrayList of HashMaps which is the default fallback. I can see the data as expected, but the mapping is not.

I think this is a bug (please correct me if I'm wrong, and give me a pointer to where I can do some read-up).

What are the proposed solutions and other options if we like to continue with the hessian RMI.

Brgds/J

Notes
(0003350)
bramk   
08-22-08 14:51   
Hi J,

without any knowledge of hessian or the specifics of your code, but with some experience with OSGi...

Many legacy (in the OSGi context) libraries use the ContextClassLoader and this is a know issue. When a call to your service is made this classloader is not your BundleClassLoader and thus you may run into problems loading classes or recources.

A common workaround is to temporarily switch the ContexClassLoader when your legacy code is invoked and switch it back when you are done. A simplified piece of code would look like..


        ClassLoader bundleClassLoader = this.getClass().getClassLoader();
        ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(bundleClassLoader);

        // invoke my legacy code

        Thread.currentThread().setContextClassLoader(originalClassLoader);

Hope this helps you out! Let me know.

Regards,
Bram

--
http://www.gxwebmanager.com [^]