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.
Related
I have this scenario where i have my EJB3 beans in a jar file, deployed successfully to Jboss EAP-6.4.
Then I have another web project that looks up these EJB's inside a REST POJO class. I can currently access the EJB's from inside the web project using #Inject and #EJB, but my use case is one that i don't know which beans i need to load until runtime and the list is not static, so i might need to lookup 10 EJB's or none for a particular request etc.
I know I can possibly use
InitialContext.lookup('ejb:/.....')
to retrieve my EJB beans from inside the web project, but is there a way that i can retrieve them without that round trip(i believe), or maybe what am just looking for is a more elegant way to do EJB look-up at runtime just like the statically typed #EJB and #Inject versions.
Any suggestions are greatly appreciated.
EDIT
In my REST POJO classes i don't want to hard code any #Inject or #EJB annotations, rather i want that when a request comes in i look-up(for lack of better word) the EJB's that will handle the request, so all the decision is made at runtime really, as shown below
#Path("/path")
public class TestService {
#GET("/{id}")
public String loadGetPath(#Param id int id){
//at this point i want to dynamically resolve the EJB based on
//the value of id
}
}
Whoopdicity blog: Developing a dynamic JEE service client with CDI seems to have what you are looking for. At the end it claims you can do:
public class MyServiceConsumer {
#Inject #ServiceClient
private MyBusinessService service;
...
}
Instead of
public class MyServiceConsumer {
#EJB(lookup="...")
private MyBusinessService service;
...
}
What is the best practice in java EE?
Create an instance of the DAO class in the service (or manager) class
SalesDAO salesDao = new SalesDAOImpl();
salesDao.findCustomers();
or
Call a DAO EJB in the service (or manager) class
#EJB
private SalesDAO salesDao;
salesDao.findCustomers();
The second one is the best practice (your DAO could be a CDI bean: it doesn't have to be an EJB).
Dependency injection is what makes the code testable: you can inject a mock DAO in the service when unit-testing the service.
BTW, the DAO will also need to have a DataSource or an EntityManager injected to be able to get data from the database. This is only possible if the DAO instance is managed by the container.
I preffer the second one.
DAO talks about responsability, means manage persistent data. But there is no reason for not to use a EJB. Let the container manage instances for you.
Adam Bien, member of EJB 3.1 spec comitee said in his blog:
http://www.adam-bien.com/roller/abien/entry/generic_crud_service_aka_dao
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 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.
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.