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