1

我的应用服务器是 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;

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

我已经提到EJB 应该是实例变量并在 JSF Managed Beans 中标记为瞬态吗?其中提到不需要将 EJB 标记为瞬态;那么有什么问题呢?

4

1 回答 1

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

序列化成功。

结论:

远程接口的内在机制是获取存根或代理,以允许使用此代理模式进行客户端-服务器通信。这涉及数据的编组和解组,因此代理存根默认是可序列化的,因此 EJB 不需要实现可序列化接口。

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

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

于 2012-09-04T17:23:36.210 回答