EJB3.0 Serializing a handle to a Stateful Bean

2020-04-18 07:42发布

问题:

I'm attempting to persist the remote handle to a Stateful EJB3.0 bean. This bean's interface is defined:

@Remote
public interface Hello extends Serializable {
     Handle getHandle();
     void sayHello();
}

The implementation is:

@Stateful
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class HelloBean implements Hello {

    @Resource
    private SessionContext ctx;

    @Override
    public Handle getHandle() {
          try {
              return ctx.getEJBObject().getHandle();
          } catch (Exception e) {
              throw new RuntimeException(e);
          }
    }

    @Override
    public Handle sayHello() {
        System.out.println("hello");
    }
}

According to the EJB Spec, that should grab me a serializable handle. But instead I get:

Caused by: java.lang.IllegalStateException: EJBObject not available
    at com.sun.ejb.containers.EJBContextImpl.getEJBObject(EJBContextImpl.java:328)
    at com.zzz.zzz.HelloBean.getHandle(WorkHolderBean.java:125)
    ... 75 more

I'm not sure I understand what I did wrong... All Stateful beans should have a serializable handle. Is there a 'correct' way of obtaining the serializable handle in EJB3.0?

回答1:

getEJBObject is not usable with the EJB 3.0 programming model. You'll need to use @RemoteHome and implement EJBHome/EJBObject.



回答2:

This exception doesn't seem related to serialization problem. From J2EE API Reference you can read:

IllegalStateException - Thrown if the instance invokes this method while the instance is in a state that does not allow the instance to invoke this method, or if the instance does not have a remote interface.

and more :

An instance of a session enterprise Bean can call this method at anytime between the PostConstruct or ejbCreate and the PreDestroy or ejbRemove methods, including from within these methods.

It could be that you call getHandle method in a phase where you cannot use getEjbMethod. Maybe something goes wrong with your Session initialization (I suppose that ctx attribute is inizialized somewhere in the code you have omitted for simplicity)