Issue Details (XML | Word | Printable)

Key: GLASSFISH-12599
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Critical Critical
Assignee: Sivakumar Thyagarajan
Reporter: Harald Wellmann
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
glassfish

Injected Session Bean not serializable when it should be

Created: 09/Jul/10 01:16 AM   Updated: 29/Nov/11 04:22 AM   Resolved: 15/Nov/10 08:00 AM
Component/s: cdi
Affects Version/s: 3.1
Fix Version/s: 3.1_ms07

Time Tracking:
Not Specified

Environment:

Operating System: All
Platform: All


Issuezilla Id: 12,599
Status Whiteboard:

weld-int-required

Tags:
Participants: buddypine, Harald Wellmann, Mahesh Kannan, marina vatkina and Sivakumar Thyagarajan


 Description  « Hide

I have a stateless session bean Foo (no-interface local view) which implements
Serializable.

When I inject this bean into a client class FooClient, in one of the following ways,

@Inject
private Foo foo;

or

@EJB
private Foo foo;

the injected member foo fails to serialize and deserialize correctly.

I tested this using writeObject(foo) to a stream followed by readObject(...)
from that stream.

In the first case (@Inject), I get a null pointer exception when calling any
method on the object returned by readObject().

In the second case (@EJB), writeObject(foo) fails because
com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate is not serializable.

In the first case, the injected instance is a javaassist proxy wrapping a
Glassfish proxy wrapping the Foo implementation. The javasssist proxy appears to
be broken as reported in https://jira.jboss.org/browse/JASSIST-97.

After patching the weld-osgi-bundle.jar with javassist-3.12.1.GA which fixes the
bug, I ran into the same problem with EJBLocalObjectInvocationHandlerDelegate as
in the second case.

To sum up:
1) Glassfish needs to ensure that any proxy it generates for a serializable EJB
is also serializable.

2) Weld needs to be upgraded to a newer version containing the Javassist bugfix.



Sivakumar Thyagarajan added a comment - 13/Jul/10 10:40 AM

As part of Weld 1.1, there is work going in the Weld SPI around better handling
of serialization of dynamically created client proxies and we are handling this
as part of GF3.1.

Is FooClient a Java EE application client or a Servlet/EJB/ManagedBean where the
injection is being done? Could you explain the use-case on why you explicitly
serialize the injected bean? Could you please share the application (client) and
the NPE stack-trace?


Harald Wellmann added a comment - 14/Jul/10 12:37 PM

My application uses Wicket for the web UI, and Wicket serializes each page to
the page store at the end of the HTTP request.

Session beans get injected into my Wicket components for communicating with the
backend.

As I said, it is completely trivial to reproduce the problem construct in a
simple test case using writeObject() on a HelloWorld SLSB, and this is
absolutely independent of Wicket.

This test also fails when using @EJB à la Java EE 5 instead of @Inject, so I
would think that Weld does not enter the scene, and this part of the problem is
entirely on the Glassfish side - assuming that
com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate is within the
Glassfish domain and not third-party code.


Harald Wellmann added a comment - 14/Jul/10 12:38 PM

My application uses Wicket for the web UI, and Wicket serializes each page to
the page store at the end of the HTTP request.

Session beans get injected into my Wicket components for communicating with the
backend.

As I said, it is completely trivial to reproduce the problem in a simple test
case using writeObject() on a HelloWorld SLSB, and this is absolutely
independent of Wicket.

This test also fails when using @EJB à la Java EE 5 instead of @Inject, so I
would think that and this part of the problem has nothing to do with Weld and is
entirely on the Glassfish side - assuming that
com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate is within the
Glassfish domain and not third-party code.


Mahesh Kannan added a comment - 07/Oct/10 04:28 PM

Assigning this to Marina.

Marina: Check with Linda if Local EJB references have to be Serializable


marina vatkina added a comment - 11/Oct/10 02:22 PM - edited

Seems like a CD issue: neither the CDI spec nor the EJB spec imposes
requirements that proxies be serializable. Latest Weld expects them to be
"passivateable". Older versions of weld maybe required it to be serializable,
but weld 1.1 doesn't.


Harald Wellmann added a comment - 12/Oct/10 01:42 AM

Just to make the point clearer: The question is not whether EJB or CDI proxies
should be serializable IN GENERAL.

But when a user-defined class Foo implements Serializable, any proxy to Foo must
satisfy the contract of the original class Foo, so the proxy should be
serializable too.


marina vatkina added a comment - 12/Oct/10 10:33 AM

Neither spec require ANY proxies to be serializable, whether the bean class
implements it or not. So even if Foo implements Serializable, it's proxy is not
required to do so.


Sivakumar Thyagarajan added a comment - 13/Oct/10 09:35 AM

The weld proxy is serializable and for classes that implement serializable its
weld proxy must be serializable too. It appears that the weld de-serializable
should be fixed with an upgrade of javassist. Weld 1.1 trunk nows uses 3.13.0-GA
and once we have an integration of Weld 1.1.BETA2 with this, this issue should
be fixed. I will re-check this scenario after the integration and close this
issue for the @Inject part.


Sivakumar Thyagarajan added a comment - 22/Oct/10 01:32 AM

Marking as weld-int-required


Sivakumar Thyagarajan added a comment - 15/Nov/10 08:00 AM

Since Weld 1.1.BETA2 with the latest javassist release is integrated and a test-
case [1] that tries to reproduce this behaviour passes, I am closing this issue.

[1] https://svn.dev.java.net/svn/glassfish-svn/trunk/v2/appserv-
tests/devtests/cdi/javaee-integration/no-interface-local-view-proxy-serializable


buddypine added a comment - 24/Nov/11 07:52 AM

There is an error in the tests, the SLSB is actually marked as @Stateful - but the test still passes when changed to @Stateless.

However if I directly inject the SLSB into the servlet then try to serialize the injected proxy it fails with a NotSerializableException.
Should the injected SLSB proxy not be serializable?

@WebServlet(name = "mytest", urlPatterns = { "/myurl" })
public class NoInterfaceProxySerializableEJBTestServlet extends HttpServlet {

    @Inject
    HelloNoInterfaceLocalViewSlessEJB helloNoInterfaceLocalViewSlessEJB;
..
[#|2011-11-24T08:45:26.535+0100|SEVERE|glassfish3.1.1|
javax.enterprise.system.std.com.sun.enterprise.server.logging
|_ThreadID=22;_ThreadName=Thread-6;|
java.io.NotSerializableException: test.ejb.__EJB31_Generated__HelloNoInterfaceLocalViewSlessEJB__Intf____Bean__

marina vatkina added a comment - 28/Nov/11 10:54 PM

Do you have beans.xml in the your module? If not, local EJB reference is not serializable without CDI being enabled.