Serialization problem with CDI, EJB and Proxies
hwellmann Jul 8, 2010 5:10 AMI'm using CDI to @Inject a stateless session bean Foo (no-interface local view) into a serializable bean Bar. Foo is Serializable, so I should be able to serialize and deserialize Bar without problems, but this does not work.
(Actually, I'm not doing this manually: Bar is a Wicket component which gets (de-)serialized automatically when navigating from page to page, and there is a ComponentInstantiationListener taking care of injection on component construction, using InjectionTarget.inject(), much like in weld-wicket.)
With Glassfish 3.01b21, I get the following exception
java.lang.NullPointerException: null at javassist.util.proxy.RuntimeSupport$DefaultMethodHandler.invoke(RuntimeSupport.java:37) at org.javassist.tmp.java.lang.Object_$$_javassist_224.fooMethod(Object_$$_javassist_224.java)
Apparently, the javassist proxy for my Foo object does support serialization in principle, but it fails to (de)serialize the method handler.
I searched the Weld and Javassist archives to see if this was a known problem, and I found this bug (https://jira.jboss.org/browse/JASSIST-97) which is reported to be fixed in javassist-3.12.0, which is newer than the version of Javassist bundled with the version of Weld used by Glassfish v3.0.1b21
I unpacked the weld-osgi-bundle.jar, replaced the javassist classes by the ones from javassist-3.12.1.GA, repacked everything and launched my Glassfish instance with this modified bundle to see if this problem was solved.
After this change, I got a different serialization problem:
org.apache.wicket.util.io.SerializableChecker$WicketNotSerializableException: Unable to serialize class: com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate protected java.lang.reflect.InvocationHandler java.lang.reflect.Proxy.h [class=com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate] <----- field that is not serializable
Using @EJB instead of @Inject produces the same exception.
So it seems, however hard I try to make my session bean serializable, Glassfish and/or Weld will always give me an unserializable proxy to it. Or in other words, CDI should be transparent, but is not, and I really have no clue how to get out of this situation...
There is a Wicket extension javaee-inject (supporting Java EE 5 injections, but not CDI) which works with special serialization handlers, replacing a proxy by a reference on serialization and doing a lookup with that reference on deserialization.
Sounds like this might solve the problem if Weld would handle EJB injections in a similar manner.
Any other ideas....?
Best regards,
Harald