I have the following configuration:
- 1 EAR on one GF containing 2 EJB-JARs with EJB components.
- 1 WAR on another Glassfish server (=> other JVM) containing web components accessing the EJB components.
I have 2 EJB business services in each EJB-JAR of my EAR, and they are all developped like this:
@Remote
public interface ServiceAItf {
...
}
@Stateless
@Local
public class ServiceAImpl implements ServiceAItf {
...
}
In my WAR, I access the EJB components via an explicit "InitialContext.lookup" on the remote interface.
In my EAR, I am quite confused about the best practice for injection, in terms of performance, architecture, and so on...
I have the following questions:
As you can see, I have declared the annotation "@Local" on the service implementation without defining the local interface. Is it correct? At least I have no error at deployment. But maybe I should use the "@LocalBean" annotation instead? I suppose that the "@LocalBean" annotation simply allows to invoke the implementation directly as a "Local" EJB, but you have to use the implementation in your code like this:
@Stateless @Local public class ServiceBImpl implements ServiceBItf { @EJB private ServiceAImpl serviceA; ... }
What is the best way to inject one EJB into another one? It works like this:
@Stateless @Local public class ServiceBImpl implements ServiceBItf { @EJB private ServiceAItf serviceA; ... }
But from what I noticed, the "serviceA" injected is the remote proxy, while it is in the same JVM within the same EAR file. So I suppose that there will be an impact on the performance. That's why I have tried to inject the service like this:
@Stateless
@Local
public class ServiceBImpl implements ServiceBItf {
@Inject
private ServiceAItf serviceA;
...
}
But it doesn't work in GF, I have the following exception:
WELD-001408 Unsatisfied dependencies for type [...] ...
I then tried to create a local interface, and the injection via the annotation "@Inject" works when both services
Even if I create a local interface like this, the service is not injected via the annotation "@Inject" but is null:
@Local
public interface ServiceALocalItf {
...
}
I read a lot of articles where it is highly recommended to use "@Inject" instead of "@EJB" when it is for a local invocation. That leads me to the following question: in which case the "@Local" EJB invocation is recommended (or simply used)?
After all this analysis, I come to the following conclusion:
- For each service, I create a "@Local" and a "@Remote" interface.
- From WAR to EJB-JAR of EAR, make a JNDI lookup to the remote interface.
- From EJB-JAR to EJB-JAR, make an injection via "@EJB" to the local interface.
- For two services within the same EJB-JAR, make an injection via "@Inject" to the local interface.
What do you think about it? Is it correct?