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.
Related
In terms of objects created at run time by the application server, what is the difference between
making of a bean both an EJB and a JAX-RS resource
#Stateless
#Local
#Path("current")
public class Facade
{
#PersistenceContext
EntityManager entityManager;
#EJB
...
// methods
}
using two different beans
#Path("current")
public class Facade
{
#EJB
private MyEjb myEjb;
// methods
}
#Stateless
#Local
public class MyEJB
{
// methods
}
Thanks for your answers!
EDIT:
ahah maybe my real questions would be about what's the result of using jax-rs annotations on an EJB, but that' basically the same question I asked.
It works. But if we stick to Oracle specification, exposing an EJB as a Web Service (rest or soap) is a kind of quick solution, with you promising to revisit this approach in the nearest future :-)
Infact, again sticking to what Oracle say, the EJB should reside on the business layer, and the web service should be in the integration layer.
I am not arguing that exposing an EJB is a wrong approach, but just because it is quite easy to develop rest service in Java, I would create a façade class, and transform in a service. Then I would inject the EJB into the class, or by jndi lookup if it is a rest. To have better separation of concerns.
This way you don't end up with a single class stuffed with annotation, but you are introducing flexibility, and have an architecture that may evolve, for example maybe you can decide in the future to deploy the business layer on a dedicated machine...whatever.
I have a Spring 3 project which acts as a Rest API, and wanted to wire a spring bean I have into an unmanaged class for logging purposes.
After trying many different things, what worked was marking my unmanaged class with the annotation #Configurable.
Like:
#Configurable
public class ClassNotManagedBySpring {
#Autowired
#Qualifier("myBean")
private MyBean myBean;
}
#Service("myBean")
public class MyBean {
#Autowired
#Qualifier("someOtherBean")
private SomeOtherBean someOtherBean;
}
And then in my beans.xml:
<context:spring-configured/>
So now let's say that ClassNotManagedBySpring.java, is one of 6 classes that all do something similar, except 3 of them ARE managed by spring because they have the #Component annotation.
But all 6 of these classes need to #Autowire MyBean.java and only some need the #Configurable annotation.
To note, I was already previously using AspectJ in this app for multiple other purposes.
I want to know what is the risk in my spring application by all of a sudden wiring spring managed dependencies into un managed classes in this way?
Can there be performance issues? Risks of errors at runtime?
If this isn't the best way of wiring a spring managed bean into an unmanaged class, what is?
I've been using #Configurable for years without issues, it's a very easy solution if you need app instantiated beans configured by Spring. My use cases were all in the UI tier. I also used #Configurable(preConstruction = true) whenever I needed autowired values already in the constructor. Of course, if you make millions of #Configurable objects it might be a performance issue, otherwise I wouldn't worry too much about it. The only small aesthetic problem I had was Eclipse giving me some red underlines at class definitions extending #Configurable classes, complaining that the hierarchy of class SomeClass is inconsistent, but it compiled them nevertheless, no errors in the Problems view or at runtime whatsoever.
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...
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.
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.