【问题标题】:Why does my EJB interface need to extend serializable?为什么我的 EJB 接口需要扩展可序列化?
【发布时间】:2014-06-26 18:56:46
【问题描述】:

我试图弄清楚这是怎么回事,但我无法真正解释为什么。

我有一个我一直在使用的极其简单的 EJB 3 实现(部署到独立的 OpenEJB 3.1.2 容器中)。

如果我设置一个看起来像这样的界面/实现......

用户服务(接口)

public interface UserService {
    public String doStuff(String myParam);
}

UserServiceBean(实现)

@Stateless
@Remote({UserService.class})
public class UserServiceBean implements UserService {
    public String doStuff(String myParam) {
        return "Did stuff!";
    }
}

...这很好用(即我可以部署到我的 OpenEJB 独立容器并运行涉及 JNDI 查找和服务调用的快速测试,返回预期的“Did stuff!”值)。

但是,一旦我将我创建的 POJO 引入到我的方法签名中,如下所示:

用户服务(接口)

public interface UserService {
    public User lookupUser(String myParam);
}

UserServiceBean(实现)

@Stateless
@Remote({UserService.class})
public class UserServiceBean implements UserService {
    public User lookupUser(String userName) {
        return new User();
    }
}

...我的 POJO 的样子:

public class User implements Serializable {
    private String userName;
    private String firstName;
    private String lastName;
    private String employeeClassCode;
    private Date termDate;
    // Getters & Setters follow
}

我现在收到来自 OpenEJB 容器的 FATAL 报告:

2014-06-26 12:41:32,182 - FATAL - Couldn't write EjbResponse to output stream
java.io.NotSerializableException: UserServiceBean

正如错误日志会让你相信,解决方法是让我的 UserService 接口扩展 Serializable - 一旦我这样做,一切都很好......但我真的很难理解为什么 EJB bean 本身需要只有在我将 POJO 添加到方法签名后才能序列化。谁能解释一下?

顺便说一句,我的问题很清楚,我 100% 可以回答 general 问题“为什么在使用 EJB 时需要序列化?”我的具体困惑点是为什么bean本身突然需要可序列化只是因为方法签名中使用了可序列化对象。

【问题讨论】:

  • @MrMojoRisin code ticks用于库或软件名称,而用于代码。不确定您的修改是如何获得批准的,但请记住这一点。
  • 我同意了——对不起,我比较了解,认为他一定知道我不知道的事情,所以我同意了。
  • 如有疑问,请跳过或ask on meta
  • 好的,谢谢你的提示!

标签: java serialization ejb-3.0


【解决方案1】:

编辑:原来的答案有点懒;添加更多说明。

哇,这太离奇了——我的 User.java 列表中的完全并不完整。我实际上在做的是:

return new User() {
    {
        setFirstName("Fernando");
        setLastName("Alonso");
    }
};

你不会认为这会是个问题,但是当我把它改成更正统的时候:

User user = new User();
user.setFirstName("Fernando");
user.setLastName("Alonso");
return user;

它就像一个魅力!问题是,使用我的原始代码,我正在创建我的用户 POJO 的匿名子类。对于 JVM,这与 User 类的实例完全不同,而是一个存在于 UserServiceBean 本身中的匿名类。举例说明:

User anonymousUser = new User() {
    {
        setFirstName("Fernando");
        setLastName("Alonso");
    }
};

检查anonymousUser 引用变量发现它指向UserServiceBean$1 的一个实例(“$1”部分是Java 识别匿名内部类的方式)

做更传统的:

User user = new User();
user.setFirstName("Fernando");
user.setLastName("Alonso");

检查 user 引用变量会发现它是 User 类的一个实例(如您所料)。

因此,有了这些信息,表明UserServiceBean 本身需要可序列化的原始错误现在非常有意义!

【讨论】:

  • 匿名内部类不是静态的,这意味着它们具有对包含实例的隐式引用。在您的情况下,这意味着匿名用户具有对 UserServiceBean 的隐式引用,您可以看到 NotSerializableException 报告的内容:隐式引用不可序列化。
猜你喜欢
  • 2015-12-05
  • 1970-01-01
  • 1970-01-01
  • 2017-03-18
  • 2011-02-28
  • 2012-11-06
  • 1970-01-01
  • 2022-12-22
  • 1970-01-01
相关资源
最近更新 更多