【问题标题】:EJB not serialized in Managed BeanEJB 未在托管 Bean 中序列化
【发布时间】:2012-06-30 16:16:42
【问题描述】:

我的应用服务器是 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 标记为瞬态;那么有什么问题呢?

【问题讨论】:

  • 你用的是什么容器?
  • EJB 方法的返回类型和参数是否可序列化。
  • @NayanWadekar:嗯?这究竟是如何导致这个问题的?
  • @BaluC:使用 WebSphere Application Server V8。
  • @NayanWadekar:我们需要将 EJB bean 标记为可序列化吗?我有 2 种方法,一个将字符串作为输入并返回 LinkedHashMap,另一个字符串作为输入,字符串作为输出

标签: jsf-2 websphere ejb-3.0


【解决方案1】:

在具有本地和远程接口的 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。

b.带远程接口(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 特定的解决方案

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-26
    • 2012-01-27
    • 2012-07-30
    • 2014-11-29
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    • 2011-03-03
    相关资源
    最近更新 更多