EJB未在Managed Bean中序列化

时间:2012-06-29 05:40:30

标签: jsf-2 websphere ejb-3.0

我的应用程序服务器是WebSphere Application Server V8。我有一个会话范围的托管bean,我在其中使用@EJB注释注入了EJB(EJB 3.0)。 EJB是无状态的。

   @ManagedBean
   @SessionScoped
    public class MyBean extends BaseBackingBean implements
    Serializable {

@EJB
private IDetails custInfo;

我正在分析会话数据并注意到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 

现在我尝试将EJB标记为瞬态,并且在没有抛出NotSerializableException异常的情况下工作正常。

@EJB
private transient IDetails custInfo;

这是正确的实施还是可以替代的解决方案?

我已经提到Should EJBs be instance variables and marked as transient in JSF Managed Beans?,其中提到将EJB标记为瞬态不是必需的;什么可能是错的?

1 个答案:

答案 0 :(得分:3)

在WAS V8上实现了具有本地和远程接口的POC代码,注意以下内容:

<强>一个。使用Local接口(EJB不实现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);

这导致 java.io.NotSerializableException:com.ibm.test.SerializableTestEJB 在java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:.. 为了防止这种情况,EJB必须显式实现Serializable。

<强>湾使用远程接口(EJB不实现可序列化)

//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);

序列化成功。

结论:

远程接口的固有机制是获取存根或代理,以允许使用此代理模式进行客户端 - 服务器通信。这涉及数据的编组和解组,因此默认情况下proxy-stub是Serializable,因此EJB不需要实现Serializable接口。

但本地接口不涉及远程查找和存根处理程序。 EJB初始化类似于初始化本地可用类,因此默认情况下序列化不可用。在这种情况下,要么EJB需要实现可序列化的接口,要么需要将对象声明为瞬态以跳过序列化。

我将变量声明为瞬态变量。这可能是WebSphere特定的解决方案