EJB3.1 - possible to start #EJB injection chain without JNDI lookup? - java

I am using EJB3.1 deployed to JBoss AS 5.1, so I'm using the #EJB injection. It works great when called from another EJB. Like this bean:
#Stateless (mappedName = "daos/MyDao")
public class MyDAO implements MyDaoRemote {
#PersistenceContext(unitName = "myEm")
private EntityManager em;
which is injected into this other bean
#Stateless(mappedName = "handler/MyHandler")
public class MyHandler implements MyHandlerRemote {
#EJB(mappedName = "daos/MyDao")
private MyDaoRemote myDao;
However, my application starts from a POJO. I don't think you can use the #EJB injection outside of a EJB... SO, is it possible to get MyHandler without using a JNDI lookup? This code works:
return (MyHandlerRemote) new InitialContext().lookup("handler/MyHandler");
but I would love to avoid doing this lookup. In Seam and Spring, it seems like the scanning of classes for annotations is easier.
I probably don't NEED #EJB injection, but I like having the container manage the PersistenceContext for me, and the auto-wiring.
Seems like Weld could help, but I don't think it will work in JBoss AS 5.1, as could Spring, but it seems like there should be a starting point for EJB without JNDI lookups.
Thanks in advance.

You can use Seam for injecting EJBs in POJOs running under JBoss AS 5.1, without the need for making a JNDI lookup - instead, using Seam's #In annotation.

Related

#Inject annotation not working

I'm trying to use CDI for the first time. While I have successfully injected one EJB inside another using #EJB, I can't get the #Inject annotation to work.
#Stateless
public class AccountDaoImpl implements AccountDAO {
#Inject
private MultiTenantEntityManagerImpl mtem; //always null
}
And the multi-tenancy entity manager looks like this:
#Default
public class MultiTenantEntityManagerImpl {
.....
}
I've created a beans.xml file (empty) but and shoehorned it into the META-INF folder in the built jar file. Still no joy.
I'm sure it's something simple. I'm running in jboss 5.0.1.GA.
Update
So it looks like the #Inject annotation is not supported in jboss 5.
An alternative is to use the #EJB annotation, but this isn't working either:
#Stateless
public class AccountDaoImpl implements AccountDAO {
#EJB
private MultiTenantEntityManager mtem; //still null!
}
Weirdly, in another EJB, this exact declaration of the entity manager is working fine.
in my case i was missing subsystem in the standalone
It looks like, in jboss 5 at least, an #EJB annotation will only be respected if both the following conditions hold:
The class in which you're using it is an EJB
The class is retrieved from the container somehow (eg JNDI), rather than being simply instantiated via a constructor.

CDI #Inject or plain old java ee 5 annotations

Let's say I have stateless EJB as below:
#Stateless
public class MyService {
#PersistenceContext(unitName="persistence")
private EntityManager em;
...
}
So this is injection with java ee 5 annotations e.g. #PersistenceContext.
If I use CDI I can't simply use #Inject, right? I need to create producer for this an use qualifier as below
class DBProducer {
#Produces
#PersistenceContext(unitName = "persistence")
#MyDatabase
private EntityManager em;
}
I don't mind the LOC amount. My question is what way should I use? Is it ok to mix those two: CDI #Inject and those old Java EE 5 annotations like #EJB, #PersistenceContext etc, or is it better to stick to CDI and use it everywhere?
You could do either one. The difference is pretty minor for most people (do I get a proxy or the actual object?).
Not everything can be injected with '#Inject' yet.
Eventually everything should move to that, but it may be Java EE 9 or even 10 before that happens I'm afraid.
Having #Inject everywhere should make it more straightforward for alternatives and extensions to be configured.

Does CDI offer an api for a default producer?

I have a bunch of dependencies written as fast binary web services (aka Ejb3.1). Here is the service delcaration:
#Remote
public interface MyService {...}
You would inject an EJB into a servlet or managed bean with the following syntax:
#EJB
MyService myService;
I don't want to use the #EJB injection however. I'd like to use plain vanilla CDI:
#Inject
MyService myService;
One way to accomplish this would be to Create a #Produces method for every EJB:
#Produces MyService produceMyService(InjectionPoint ijp){
//jndi lookup for MyService interface
}
However, InjectionPoint is capable of giving you all the information you need, such as the target class name (MyService in this case).
Is there a way in CDI to do something like this? I'd want to call this producer last, if the required injection point couldn't be fulfilled in any other manner.
#Produces Object produce(InjectionPoint ijp){
Class ejbInterface = ijp.getType();
//jndi lookup for ejbInterface
}
This is a confusing post, so ask clarification questions. Thanks a ton!
Assuming that I understood your question (see comment): No, there is no API for this.
Good news is that there is a way to achieve this - but you probably don't want to do this at runtime, that's rather a task for application startup.
The CDI extension mechanism offers you some well defined hooks into bean processing at container startup. This is a perfect place for logic that decides about enabling / disabling of certain managed beans (probably based on static classpath information).
Have a look at function and implementation of Seam Solder's #Requires. That should be pretty close to your use case...

how to Inject an EJB into a java class

I want to inject an EJB3 into a java class which is not an EJB.
these classes are both on the same server and application.
Is that possible ...and if yes ..then how ?
Thanks,
Perhaps you should supply more information about your work environment. The usage of CDI changes the whole specturm. You can inject it when you use CDI, otherwise you can only inject it into other EJB's and servlets (if your application server supports it).
Otherwise you can do a lookup using
Context ctx = new InitialContext();
MyEjb ejb = (MyEjb) ctx.lookup("java:comp/env/myEjb");
You can supply a name in the #EJB annotation you supply together with your #Stateless/#Stateful annotation.
#Stateless
#EJB(name="myEjb", beanInterface=MyEjb.class)
public class myEjbImpl implements MyEjb{
// code goes here
}
You can't inject it, but you can make a lookup for that EJB:
Look here:
http://www.roseindia.net/ejb/ejb-lookup.shtml
During the deploymentprocess of your EJB you may see, the Name of your Bean.

EJB 3.1 #EJB Injection into POJO

With the new EJB 3.1 spec is it possible to inject an EJB into a pojo? I know in EJB 3.0 the #EJB annotation could be used to inject an EJB but this did not work on simple pojos.
If it is not do I have to look the bean up in JNDI as I know you cannot simple use the new keyword.
With the new EJB 3.1 spec is it possible to inject an EJB into a pojo? I know in EJB 3.0 the #EJB annotation could be used to inject an EJB but this did not work on simple pojos.
Injection of EJB into an POJO is possible IF you use JSR-299 (Java Contexts and Dependency Injection) i.e. if your POJO is a CDI managed bean. In that case, you could do:
#Inject MyEJB service
But this is not an EJB 3.1 feature, this comes from CDI. And if you're not using CDI, you'll have to do a lookup.
Yes, use JNDI lookup.
Since your POJO is created by you (I assume), the container is not responsible for injecting the dependencies.
The new EJB spec (3.1) adds the ability to specify global JNDI names for EJBs. This means that you can use them in any bean, anywhere.
You must do an explicit JNDI lookup, however, as an EJB 3.1 container will not know about your POJO.
The only exception, which I'm guessing does not apply to you, is if your POJO is really an application client, in which case provided the field that is to contain the EJB is static, you may apply the #EJB annotation to it. If that's your situation, you should check out the application client rules in the overall Java EE 5 specification.
Finally, Java EE 6, with its inclusion of JSR-299, may allow what you describe to happen in some way; I do not know the spec yet so cannot comment on it.
I hope this all helps.
I wonder too if I could inject EJBs into unmanaged objects. See the Weld (JSR 299 reference implementation) documentation for more details.
But you can perform dependency injection by hand inside a repository or factory like this:
#Stateless
public PojoRespository {
#Inject
ResourceForPojos resource;
#PersistenceContext
private EntityManager em;
public Pojo findById(Object id) {
Pojo p = (Pojo) em.find(Pojo.class, id);
p.setResource(resource); // injects resource
return p;
}
}
If you have many methods where injection should be performed, you could use an interceptor.

Categories