StarsSky
StarsSky

Reputation: 6711

Inside EJB lookup: constructor, @PostConstruct

I'm studying the insight of EJB lookup and trying to understand how the container and the pool works. I created some test application, each of one I'm going to explain.

First implementation: lookup inside constructor

    @Stateless
    public class EjbTest {

    protected EjbInjectedLocal      ejbInjected;

    public EjbTest() {
            InitialContext ic = new InitialContext();
            ejbInjected = (EjbInjectedLocal)ic.lookup("java:comp/env/ejb/EjbInjected");
            ic.close();
    }

    public void test() {
        ejbInjected.callSomeMethod();
        return;
    }

}

Injection is performed inside the class constructor (bad practice), but everything works. The constructor retrieve a Proxy for the EJB. When I call the method test(), it's executed correctly.

Second implementation: lookup inside @PostConstruct

@Stateless
public class EjbTest {

    protected EjbInjectedLocal      ejbInjected;

    public EjbTest() {
    }

    @PostConstruct
    public start() {
            InitialContext ic = new InitialContext();
            ejbInjected = (EjbInjectedLocal)ic.lookup("java:comp/env/ejb/EjbInjected");
            ic.close();
    }

    public void test() {
        ejbInjected.callSomeMethod();
        return;
    }

}

As the prior example, the lookup works fine as well the method test.

Third implementation: lookup inside constructor and function execution

@Stateless
public class EjbTest {

    protected EjbInjectedLocal      ejbInjected;

    public EjbTest() {
            InitialContext ic = new InitialContext();
            ejbInjected = (EjbInjectedLocal)ic.lookup("java:comp/env/ejb/EjbInjected");
            ejbInjected.callSomeMethod();
            ic.close();
    }

}

With this implementation, the lookup works fine, but the function halt/freeze the thread, as the container is not yet ready to return NOT the proxy implementation, but the whole EJB and the function cannot be performed.

When the constructor is called, the bean is not yet initialized and no dependencies are injected? Only the proxy is returned but it's not yet available and cannot be retrieved the whole EJB from the pool?

Upvotes: 1

Views: 1345

Answers (2)

hugh
hugh

Reputation: 2280

From the EJB specification (4.3.10.2):

Since stateless session bean instances are typically pooled, the time of the client’s invocation of the create method need not have any direct relationship to the container’s invocation of the PostConstruct/ejbCreate method on the stateless session bean instance.

This is container-specific behaviour, the specification leaves it open as an area for implementors to innovate. Implementations aren't even required to use bean pool, and any lazy-loading behaviour and the exact sequence beans become available is up to the container, as is the configuration they offer their users, for example:

http://docs.jboss.org/ejb3/docs/reference/1.0.7/html/SessionBean_and_MDB_configuration.html

About the sequence of calls during instantiation, the specification (section 4.3.10) says:

The container creates an instance of a session bean as follows. First, the container calls the bean class’s newInstance method to create a new session bean instance. Second, the container performs any dependency injection as specified by metadata annotations on the bean class or by the deployment descriptor. This includes the bean’s SessionContext, if applicable. Third, the container calls the PostConstruct lifecycle callback interceptor methods for the bean, if any. The additional steps described below apply if the session bean is invoked through the EJB 2.1 client view APIs.

In particular, any dependency injected fields (i.e. using EJB annotations) will be null at this point. By using the InitialContext you've bypassed this constraint, and this is the cause of the unexpected behaviour.

From the behaviour you've described it sounds as though your container is constructing the beans first, so that the EjbInjectedLocal bean is not available at the point you're trying to call it. I'm surprised it deadlocks, but not that surprised it didn't work. It would be interesting to try the same experiment on other containers and see if you get the same outcome.

Upvotes: 2

Mike Braun
Mike Braun

Reputation: 3769

Only the proxy is returned but it's not yet available and cannot be retrieved the whole EJB from the pool?

That's correct. You're simply deadlocking yourself here.

Upvotes: 0

Related Questions