Reputation: 1570
My application server is WebSphere Application Server V8. I have a session scoped managed bean in which I have injected EJB (EJB 3.0) using @EJB annotation. EJB is stateless.
@ManagedBean
@SessionScoped
public class MyBean extends BaseBackingBean implements
Serializable {
@EJB
private IDetails custInfo;
I was analyzing the session data and noticed NotSerializableException
java.io.NotSerializableException: com.ejb.EJSLocal0SLDetailsImpl_081f812d at
java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184) at
java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1537) at
java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1502) at
java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1420) at
java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) at
Now I tried to mark the EJB as transient and it works fine without throwing NotSerializableException exception.
@EJB
private transient IDetails custInfo;
Is this correct implementation or what can be alternate solution?
I have referred Should EJBs be instance variables and marked as transient in JSF Managed Beans? where it is mentioned that marking EJB as transient is not required; then what can be wrong?
Upvotes: 1
Views: 3135
Reputation: 1570
Implemented a POC code on WAS V8 with both Local and Remote interfaces, noted the following:
a. With Local interface (EJB does not implement Serializable)
// Initializing the EJB in the servlet
SerializableTestEJBLocal localSrvlt=new SerializableTestEJB();
//Try to serialize
FileOutputStream objFOS = new FileOutputStream("D:\\MYTEST\\testsrv.txt");
ObjectOutputStream objOpStr = new ObjectOutputStream(objFOS);
objOpStr.writeObject(localSrvlt);
This resulted in java.io.NotSerializableException: com.ibm.test.SerializableTestEJB at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:.. To prevent this, the EJB had to explicitly implement Serializable.
b. With Remote Interface (EJB does not implement serializable)
//Obtain Remote Stub.
SerializableTestEJBRemote seremoteSrvlt=(SerializableTestEJBRemote)PortableRemoteObject.narrow(homeObject, SerializableTestEJBRemote.class);
//Try serialization
FileOutputStream objFOS = new FileOutputStream("D:\\MYTEST\\testsrv.txt");
ObjectOutputStream objOpStr = new ObjectOutputStream(objFOS);
objOpStr.writeObject(seremoteSrvlt);
The serialization was successfully.
Conclusion:
The inherent mechanism of remote interface is to obtain a stub or proxy to allow for client-server communication occurs using this proxy pattern. This involves marshalling and unmarshalling of data and hence the proxy-stub is Serializable by default and hence the EJB does not need to implement the Serializable interface.
But the local interfaces does not involve remote look ups and stub handlers. EJB initializes is similar to initializing a locally available class, hence serialization is not available by default. In this scenario, either the EJB will need to implement serializable interface or the object will need to be declared transient to skip serialization.
I am declaring the variable as transient. This might be WebSphere specific solution
Upvotes: 3