You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by nlif <na...@dbnet.co.il> on 2008/04/03 13:27:30 UTC

Problem serializing JDK dynamic proxies

Hi all,

I am using Tomcat 6, and running in a cluster, with session-replication.
When I put in the session a JDK dynamic proxy, the serialization fails, like
so:

Apr 3, 2008 2:09:24 PM org.apache.catalina.ha.session.DeltaManager
messageReceived
SEVERE: Manager [localhost#/users]: Unable to receive message through TCP
channel
java.lang.ClassNotFoundException: app.web.user.TestBean
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:247)
        at
java.io.ObjectInputStream.resolveProxyClass(ObjectInputStream.java:676)
        at
java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1531)
        at
java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1493)
        at
java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
        at
java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
        at
org.apache.catalina.ha.session.DeltaRequest$AttributeInfo.readExternal(DeltaRequest.java:361)
        at
org.apache.catalina.ha.session.DeltaRequest.readExternal(DeltaRequest.java:255)
        at
org.apache.catalina.ha.session.DeltaManager.deserializeDeltaRequest(DeltaManager.java:619)
        at
org.apache.catalina.ha.session.DeltaManager.handleSESSION_DELTA(DeltaManager.java:1363)
        at
org.apache.catalina.ha.session.DeltaManager.messageReceived(DeltaManager.java:1320)
        at
org.apache.catalina.ha.session.DeltaManager.messageDataReceived(DeltaManager.java:1083)
        at
org.apache.catalina.ha.session.ClusterSessionListener.messageReceived(ClusterSessionListener.java:87)
        at
org.apache.catalina.ha.tcp.SimpleTcpCluster.messageReceived(SimpleTcpCluster.java:916)
        at
org.apache.catalina.ha.tcp.SimpleTcpCluster.messageReceived(SimpleTcpCluster.java:897)
        at
org.apache.catalina.tribes.group.GroupChannel.messageReceived(GroupChannel.java:264)
        at
org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:79)
        at
org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:79)
        at
org.apache.catalina.tribes.group.interceptors.TcpFailureDetector.messageReceived(TcpFailureDetector.java:110)
        at
org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:79)
        at
org.apache.catalina.tribes.group.ChannelCoordinator.messageReceived(ChannelCoordinator.java:241)
        at
org.apache.catalina.tribes.transport.ReceiverBase.messageDataReceived(ReceiverBase.java:225)
        at
org.apache.catalina.tribes.transport.nio.NioReplicationTask.drainChannel(NioReplicationTask.java:185)
        at
org.apache.catalina.tribes.transport.nio.NioReplicationTask.run(NioReplicationTask.java:88)
        at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
        at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
        at java.lang.Thread.run(Thread.java:619)

Here is the relevant code:

The servlet:

        TestBean    testBean          = new TestBeanImpl();
        Class[]     proxiedInterfaces = testBean.getClass().getInterfaces();
        ClassLoader classLoader       =
Thread.currentThread().getContextClassLoader();
        TestProxy   proxy             = new TestProxy(testBean);
        TestBean    proxiedBean       = (TestBean)
Proxy.newProxyInstance(classLoader, proxiedInterfaces, proxy);

        request.getSession().setAttribute("testBean", proxiedBean);

The TestBean interface:

        public interface TestBean {
	     public void op1();
        }

The TestBeanImpl class:

    public class TestBeanImpl implements TestBean, Serializable
    {
        public void op1()
        {
            System.out.println("doing op1");
        }
    }

The TestProxy class:

   public class TestProxy implements InvocationHandler, Serializable
    {
        private static final long serialVersionUID = 1L;
        private Object target;

        public TestProxy(Object target)
        {
            this.target                            = target;
        }

        public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable
        {
            System.out.println("proxy invoked");
            return method.invoke(target, args);
        }
    }

My application is deployed as a WAR file.

Has anyone been able to put proxies in the HttpSession and replicate
successfully?
Is this a Tomcat bug?
Is this a problem in my implementation?

Thanks
Naaman


-- 
View this message in context: http://www.nabble.com/Problem-serializing-JDK-dynamic-proxies-tp16467407p16467407.html
Sent from the Tomcat - User mailing list archive at Nabble.com.


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


Re: Problem serializing JDK dynamic proxies

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Nilf,

nlif wrote:
| Here is the code of the Wrapper:

Nice workaround. I'm not entirely sure why the ClassLoader tree is
fighting you in this case, but it's nice to know that you can beat it
into submission when necessary ;)

- -chris

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkf6NnEACgkQ9CaO5/Lv0PCxRwCdGugbxq1B7ljjg11lyRLuY7x/
b7QAoIhwhp+deMQP25frNTWYj5ro5SK0
=1WS9
-----END PGP SIGNATURE-----

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


Re: Problem serializing JDK dynamic proxies

Posted by nlif <na...@dbnet.co.il>.
Hi Chris,

Thanks for the link. I found the following workaround: instead of placing my
Proxy object in the HttpSession, I put it in a serializable wrapper class
first, and then put the wrapper in the HttpSession. The wrapper overrides
the default de-serialization to set a different class-loader as the
thread-local class-loader. Now, session replication completes without
throwing the exception. 

Here is the code of the Wrapper:

public class ProxyWrapper implements Serializable
{
    private Object Proxy;

    public ProxyWrapper(Object proxy)
    {
        Proxy = proxy;
    }

    public Object getProxy()
    {
        return Proxy;
    }

    private void readObject(java.io.ObjectInputStream in)
        throws IOException, ClassNotFoundException
    {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();

        try
        {
            ClassLoader myCl = this.getClass().getClassLoader();
            Thread.currentThread().setContextClassLoader(myCl);
            in.defaultReadObject();
        }
        finally
        {
            Thread.currentThread().setContextClassLoader(cl);
        }
    }
}

IMHO, this, as well as the dynamic-proxy documentation, implies there is a
problem in Tomcat's session-replication implementation.


Naaman
-- 
View this message in context: http://www.nabble.com/Problem-serializing-JDK-dynamic-proxies-tp16467407p16521737.html
Sent from the Tomcat - User mailing list archive at Nabble.com.


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


Re: Problem serializing JDK dynamic proxies

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Nilf,

nlif wrote:
|> Are you sure you put your test class on all of the servers?
|
| Yes. I am sure. It's there, and this happens either when replicating from
| Node A to Node B or the other way around.

Hmm... so it always fails on the receiving end? The serialization
succeeds, but the de-serialization fails?

It should /totally/ work:
http://java.sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html#serial

Where does TestClass.class live within the ClassLoader hierarchy?

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkf2L+IACgkQ9CaO5/Lv0PBy4wCZAScybCl7Wdd+Pkj2FZA9M6z2
WywAn2DGlSuYI9QdBDhZoArVKiGkTFWa
=4BGs
-----END PGP SIGNATURE-----

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


Re: Problem serializing JDK dynamic proxies

Posted by nlif <na...@dbnet.co.il>.

Christopher Schultz-2 wrote:
> 
> 
> This doesn't look like the proxy is failing; it looks like the TestBean
> class is not available to the receiving Tomcat instance. This happens on
> the /other/ Tomcat, right (i.e. not the one where the object was put
> into the session)?
> 
> Are you sure you put your test class on all of the servers?
> 
> 

Yes. I am sure. It's there, and this happens either when replicating from
Node A to Node B or the other way around. 

-- 
View this message in context: http://www.nabble.com/Problem-serializing-JDK-dynamic-proxies-tp16467407p16484982.html
Sent from the Tomcat - User mailing list archive at Nabble.com.


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


Re: Problem serializing JDK dynamic proxies

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Naaman,

nlif wrote:
| I am using Tomcat 6, and running in a cluster, with session-replication.
| When I put in the session a JDK dynamic proxy, the serialization
fails, like
| so:
|
| Apr 3, 2008 2:09:24 PM org.apache.catalina.ha.session.DeltaManager
| messageReceived
| SEVERE: Manager [localhost#/users]: Unable to receive message through TCP
| channel
| java.lang.ClassNotFoundException: app.web.user.TestBean

This doesn't look like the proxy is failing; it looks like the TestBean
class is not available to the receiving Tomcat instance. This happens on
the /other/ Tomcat, right (i.e. not the one where the object was put
into the session)?

Are you sure you put your test class on all of the servers?

- -chris

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkf03HAACgkQ9CaO5/Lv0PAKtQCgrqgQcvWhpPFy/WXaqhjPm0QW
OKEAoIJr1CuFPaRyu26PKFhK4EThW3M3
=GXyK
-----END PGP SIGNATURE-----

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