Reputation: 6711
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
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
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