为什么我的EJB接口需要扩展可序列化?

时间:2014-06-26 18:56:46

标签: java serialization ejb-3.0

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

我有一个非常简单的EJB 3实现我一直在玩(部署到一个独立的OpenEJB 3.1.2容器中)。

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

UserService(界面)

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

UserServiceBean(implementation)

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

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

但是,一旦我将我创建的POJO引入到我的方法签名中,就像这样:

UserService(界面)

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

UserServiceBean(implementation)

@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%的一般问题的回答是“为什么在使用EJB时​​需要序列化的东西?”我的特定的混淆点是为什么bean 本身突然需要可序列化的原因,因为在方法签名中使用了可序列化的对象。

1 个答案:

答案 0 :(得分:0)

编辑:原来的答案有点懒惰;增加一些澄清。

哇,这太奇怪了 - 我在我的User.java列表中并没有完全完成。我实际上做的是:

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

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

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

它就像一个魅力!问题在于,使用我的原始代码,我正在创建用户POJO的匿名子类。对于JVM,这 not 与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本身需要序列化的原始错误现在非常有意义!