Hi All, We are using Apache tribes library for presence and inter node communication within an OSGi runtime environment. We have a central node (say node A) receiving messages from other nodes ( say node B, C). The message passed is a custom class which is present as part of the API defined in a separate OSGi bundle. This custom class is Serializable.
When a send method is invoked on the GroupChannel to send the custom class message to node A then it throws an exception with the following stack trace: java.lang.ClassNotFoundException: com.sap.nm.NodeSnapshot at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:513) at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429) at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417) at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at java.io.ObjectInputStream.resolveClass(Unknown Source) at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) at java.io.ObjectInputStream.readClassDesc(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) at org.apache.catalina.tribes.io.XByteBuffer.deserialize(XByteBuffer.java:568) at org.apache.catalina.tribes.io.XByteBuffer.deserialize(XByteBuffer.java:554) at org.apache.catalina.tribes.group.GroupChannel.messageReceived(GroupChannel.java:261) at org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:84) at org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:84) at org.apache.catalina.tribes.group.ChannelCoordinator.messageReceived(ChannelCoordinator.java:253) at org.apache.catalina.tribes.transport.ReceiverBase.messageDataReceived(ReceiverBase.java:287) at org.apache.catalina.tribes.transport.nio.NioReplicationTask.drainChannel(NioReplicationTask.java:212) at org.apache.catalina.tribes.transport.nio.NioReplicationTask.run(NioReplicationTask.java:101) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) The problem is that OSGi has a totally different class loading mechanism that what is followed in java/j2ee applications. We looked at the tribes source code and found out that following piece of code is the culprit: Class: XByteBuffer.java public static Serializable deserialize(byte[] data, int offset, int length) throws IOException, ClassNotFoundException, ClassCastException { return deserialize(data,offset,length,null); } Instead of passing null to the ClassLoader[] (last argument), Thread context classloader should have been passed. What is happening is that the tribes is trying to load the class with the tribes class loader and not using the current thread classloader and is therefore not able to find the custom class. A workaround that we have adopted now is to use byte[] and set Channel.SEND_OPTIONS_BYTE_MESSAGE option while sending the message. We then explicitly recreate the object in the ChannelListener in bundle A from the bytes message. This is possible because in GroupChannel byte messages are not deserialized using XByteBuffer. It will great if anyone can investigate this issue. Best Regards, Madhav -- When I tell the truth, it is not for the sake of convincing those who do not know it, but for the sake of defending those that do