RMI client in a OSGi container
java, osgi, rmi
Solution
Standard Java serialization and OSGi don't mix well due to class visibility issues, and as RMI is built on top of serialization...
If you google around, you'll find plenty of people asking about RMI and OSGi but little in the way of concrete solutions.
I haven't sat down to investigate the particular problems of RMI and OSGi, but I did solve the problem of using Spring's `HTTPInvoker`, which still uses Java's serialization mechanism.
The problem comes down to a single class: `ObjectInputStream`
This is the guy responsible for de-serializing - and to de-serialize an object you need visibility of its class. If you have an modern IDE you can look at the inheritance hierarchy of this class and see that there are many extensions of it, including a couple of classes specific to RMI.
My solution was to use Spring's extensible implementation of `ObjectInputStream` and plug in the classloader from my bundle, so that way the de-serialization would have access to a classloader that could see my classes.
You could play around with the system bundles, but that's really a hack and I wouldn't recommend it for long-term use.
Unfortunately, OSGi still has some nasty corners that require you to dig down in the levels of abstraction to find the problem and fix it - RMI is one of those.
The Paremus guys claim to have a solution in their Service Fabric server product (an OSGi-based server) for RMI and that can be configured to work with Felix (I think Eclipse's Equinox is the default).
Problem
I need to expose a RMI-based system in an OSGi bundle. The RMI client "bundle" is a jar which I converted into a OSGi bundle using the bnd tool (I don't have access to the sources) and at least in eclipse everything seems to be fine, but when I try to connect to the RMI server, a ClassCastException is throwed, much probably because either OSGi and RMI make a funny use of the ClassLoader. How can I solve this? maybe using the RMI client jar as a "system" bundle? Here is the stack trace: ``` Blipnet OSGi service starting... com.blipsystems.blipnet.api.blipserver.BlipServerConnectionException: There was a problem connecting to the server at com.blipsystems.blipnet.api.core.blipserver.BlipServerConnectionAdapter.(Unknown Source) at com.blipsystems.blipnet.api.core.blipserver.BlipServerConnectionAdapter.(Unknown Source) at com.blipsystems.blipnet.api.blipserver.BlipServer.getConnection(Unknown Source) at dk.itu.jingling.blipnetosgi.BlipnetConnectionService.setup(BlipnetConnectionService.java:28) at dk.itu.jingling.blipnetosgi.BlipnetConnectionService.(BlipnetConnectionService.java:22) at dk.itu.jingling.blipnetosgi.Activator.start(Activator.java:32) at org.apache.felix.framework.util.SecureAction$Actions.run(SecureAction.java:1235) at java.security.AccessController.doPrivileged(Native Method) at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:658) at org.apache.felix.framework.Felix.activateBundle(Felix.java:1699) at org.apache.felix.framework.Felix.startBundle(Felix.java:1621) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:890) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:877) at org.apache.felix.fileinstall.internal.DirectoryWatcher.start(DirectoryWatcher.java:819) at org.apache.felix.fileinstall.internal.DirectoryWatcher.start(DirectoryWatcher.java:805) at org.apache.felix.fileinstall.internal.DirectoryWatcher.startAllBundles(DirectoryWatcher.java:798) at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:299) Caused by: java.lang.ClassCastException: com.blipsystems.blipnet.blipserver.cms.NewApiHandler_Stub cannot be cast to com.blipsystems.blipnet.api.core.blipserver.RemoteBlipServerConnection ```