You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Madhav Bhargava <un...@gmail.com> on 2011/12/29 13:06:26 UTC

Apache tribes deserialization issues

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

Re: Apache tribes deserialization issues

Posted by Filip Hanik - Dev Lists <de...@hanik.com>.
your workaround is valid
I would not expect thread context class loader to work, as the thread for deserializing is the thread from the tribes TCP thread pool


On 12/29/2011 5:06 AM, Madhav Bhargava wrote:
> 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
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org