简体   繁体   中英

Why does my EJB interface need to extend serializable?

I'm trying to figure out what is going on with this and I can't really reason through why.

I've got an extremely simple EJB 3 implementation I've been playing with (deployed into a standalone OpenEJB 3.1.2 container).

If I setup an interface/implementation looking like this...

UserService (interface)

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!";
    }
}

...this works great (ie I can deploy to my OpenEJB standalone container and run a quick test involving a JNDI lookup and service call that returns the expected "Did stuff!" value).

However, once I introduce a POJO that I created to my method signature, like this:

UserService (interface)

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();
    }
}

...where my POJO looks like:

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

I now get a FATAL reported back from the OpenEJB container:

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

Just as the error logging would lead you to believe, the fix is to make my UserService interface extend Serializable - once I do this, all is well...but I am really struggling to understand why the EJB bean itself needs to be serializable only after I've added my POJO to the method signature. Can someone explain?

By the way, just so my question is clear, I'm 100% fine with the answer to the general question "why do things need to be serialized when working with EJBs?" My specific point of confusion is why the bean itself suddenly needs to be serializable just because a serializable object is being used in a method signature.

EDIT: original answer was kind of lazy; adding some more clarification.

Wow, this is beyond bizarre - I wasn't entirely complete in my User.java listing. What I was actually doing was:

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

You wouldn't think this would be a problem, but when I changed it to be the more orthodox:

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

It works like a charm! The issue was that, with my original code, I was creating an anonymous subclass of my User POJO. To the JVM, this is not the same thing as an instance of the User class at all, but rather an anonymous class that lives within the UserServiceBean itself. To illustrate:

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

Inspecting the anonymousUser reference variable reveals it to be pointing at an instance of UserServiceBean$1 (with the "$1" part being Java's way of identifying an anonymous inner class)

Doing the more traditional:

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

And inspecting the user reference variable reveals to to be an instance of the User class (as you would expect).

So, with this information in hand, the original error indicating that UserServiceBean itself needed to be serializable now makes perfect sense!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM