usage of cdi's in a ejb project without jsf - java

I am learning javaEE and I read somewhere about the main usage of cdi's was back then first in jsf-managed beans with annotations like #requestscope, #applicationscope, etc.. now in newer javaEE versions the cdi got available everywhere (even in ejb beans) so the question is, how do I have to annotate a class which shall be injected inside my local stateless ejb? I am asking this because the annotations like #RequestScope and all those are from jsf but I am not using jsf. Is #Default enough since its marked as default anyway? Is #Dependent better choice?
#Stateless
public class FooEjb{
#Inject Bar b;
}
// what annotation to put here?
public class Bar {
...
}

Yes you don't need JSF to use CDI in JavaEE.
If you are using CDI without using JSF, use the scope annotations from the javax.enterprise.context package.
#Default is a qualifier which as the name suggests the default qualifier. If you have multiple implementations/instances of the same class in your container, then you can use qualifiers to distinguish.
#Dependent is a scope which is the default scope. This means it will depend on the scope of the class it's injected in. A new instance of a #Dependent class will be injected every time a new instance of the class in which it is injected is created.
To enable CDI you need to put a beans.xml file in WEB-INF directory of your web project or META-INF directory of your EAR or EJB project.

According to the java ee documentation, no annotation is required in your case. A simple POJO is an injectable bean and receive the #Default annotation. No need to use JSF.

Related

Advantage of using #EJB to inject #Stateless Bean or using directly #inject

I am working on an old project developed in EJB.
I have serviceImpl as #Stateless(mappedName = "adminService"). I have seen in my project injecting this class in other classes by
#EJB(mappedName = "java:app/adminServices/adminServiceImpl")
and other classes are part of the same EAR but different modules. This serviceImpl class is being used only in this EAR.
So my question is if we have a class that is declared as #Stateless and is not being used in other EAR. This class is being used in same EAR modules. So can't we directly use #Inject without declaring it #Stateless?
I have known for three JNDI syntax for EJB
java:global[/application name]/module name/enterprise bean name[/interface name]
java:module/enterprise bean name/[interface name]
java:app[/module name]/enterprise bean name[/interface name]
Can't I use #Inject for java:app?
Why do I need java:module in the same modules, I can directly create an object or use #Inject.
In case of java:global I can understand if you are in other JVM then you need to make RMI call to get an object if stateless bean instance is in other JVM. So I have to use java:global syntax to get stateless bean instance from other JVM even in same JVM. Because I don't think We can use #Inject to get the instance from another EAR project into your EAR.
But in same JVM and same EAR, what is need of java:app and java:module JNDI syntax to get the instance by #EJB annotation if the bean is not singleton.
I can directly use #Inject.

Bean not found by its interface after migration to WildFly

After the migration of a JEE application (from JBoss 7.1.1 to WildFly 8.2.1) our method to get CDI Beans stopped working. The application have several modules (independent JAR files) grouped into one WAR file deployed now on WildFly.
The Bean to be injected is in the module service and it is implementing the interface IProcessor:
#Loggable
#Monitorable
#Singleton
#ConcurrencyManagement(CONTAINER)
#Lock(READ)
#LocalBean
#ApplicationScoped
public class Processor implements IProcessor {
[...]
In another module of the application (common) there is the rest of the logic: the interface IProcessor and the class where we search for it.
This is how the BeanManager is retrieved:
public void keepBeanManager(#Observes AfterBeanDiscovery abd, BeanManager beanManager) {
bm = beanManager;
}
And this is how the call is done:
Set<Bean<?>> jobBeans = bm.getBeans(IProcessor.class);
I've tried printing out all deployed beans using Adam Bien's sample, at the same point as the getBeans method is called, and I can see the Processor in them. Also, if providing the full package and class name of the Processor works as a temporal hack, but using the IProcessor interface never works, jobBeans is always empty.
The module service is not visible to the module common, and this is why the injection is done using the interface.
As it was working before in JBoss and not in WildFly I assume it is related with the way the AS is handling the Beans, could it be something missing in the configuration of WildFly after the migration?
As pointed by Xavier Dury in the comments, the Bean was not found because it was annotated as #LocalBean. Removing the #LocalBean annotation fixed the issue.
From the JEE definition of LocalBean:
Designates that a session bean exposes a no-interface view
As Processor is implementing the interface IProcessor, the annotation #LocalBean should not be used.
What is strange still for me is why this was working on JBoss...

How to use #Resource annotation in servlet (or in any other Java class)?

I am experimenting with Java Dependency Injection. Many questions here on SO talk about jndi resources being wired. But I think, a java class can be wired using #Resource annotation. I have a simple servlet in which I have two properties to be wired using CDI. I am using Tomcat6, Servlet 2.5, and Weld configuration.
The servlet code:
#Inject
private HikariConnectionProperties hikariConnectionProperties;
#Resource(name = "connectionProvider")
private IConnectionProvider connectionProvider;
However I get the code compiled, deployed. But, when there is a request for the corresponding servlet I get javax.naming.NameNotFoundException: Name connectionProvider is not bound in this Context.
But, I have #Named annotation for the ConnectionProvider class. The same configuration works with #Inject for both the fields.
So, my first question is how can I fix this issue? And is there any way that I can specify scope for a particular injection(using only annotations of JSR) without using Spring's #Scope? Any example is a great help as I am a newbie to CDI.
#Resource only works in Tomcat when you set up a resource in your container. Here's a reference for your own sake: http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html
It expects that you're binding a JNDI entry called "connectionProvider" in Tomcat. CDI does not bind elements to JNDI, it has its own internal mapping of objects to scopes. #Inject works here as you likely have not setup a resource for this class in your resource configuration.

Java EE Bean inject into another Bean

I'm making two beans say ABean and BBean. I want to inject BBean into ABean but this is causing null pointer errors, likely because the bean has yet to be instantiated. How can I inject beans in beans as such:
#Singleton
public class ABean {
#Inject
BBean bean;
....
}
I'm using java ee 7 with wildfly server. Both beans are singletons so BBean is also declared as:
public class BBean {
#PostConstruct
public void startup() {
..
}
..
}
With out the dependency, I'm able to create both beans as I do have the necessary META-INF folder and beans.xml file with in it. I'm however coming to the conclusion that this might be bad practice/ anti-pattern. Anyway I'm not using this approach anymore.
Perhaps you forgot to add the beans.xml file, in order to enable CDI in your application. This is what the Java EE 6 Tutorial says http://docs.oracle.com/javaee/6/tutorial/doc/gjbnz.html:
An application that uses CDI must have a file named beans.xml. The file can be completely empty (it has content only in certain limited situations), but it must be present. For a web application, the beans.xml file must be in the WEB-INF directory. For EJB modules or JAR files, the beans.xml file must be in the META-INF directory.
did you remember to include a setter so the bean can be injected? #Inject does not work like #EJB.
also, like previously indicated, do not try to use the bean until after the owning bean is instantiated (not in constructor, only in #PostConstruct'ed method)
hope that helps.

dependency injection in a servlet 3.0 web app?

I'm trying to write a servlet 3.0 web app, just to learn basic servlet handling. Normally i would use spring.
Now I have a servlet which access a DAO which queries the database. Now, what is the best way to instantiate that DAO and use it? My best guess would be to have a private property in the servlet and create an instance of the DAO when the servlet is created.
But, will the servlet be created multiple times?
Is there something similar to springs dependency injection available in servlet 3.0?
EJB 3 dependency injection is extremely simple to use. A single annotation, #EJB, causes the injection of a declared bean. The injection of the SomeDAO bean into a Servlet 3.0 looks like this:
#WebServlet(name="Messenger", urlPatterns={"/Messenger"})
public class Messenger extends HttpServlet {
#EJB
SomeDAO someDAO;
}
The injected SomeDAO bean could be an interface or a no-interface view bean. As long as there is only one implementation of the interface, it will be injected without any ceremony.
javax.servlet API is one of the technologies included in java-ee.
CDI, is the Context and Dependency Injection technology in java-ee
So to answer your question, your use case could be solved by using only CDI and Servlets.
But most of the application servers that supports above (e.g. TomEE, Glassfish webprofiles), will also support EJB (which uses cdi) and JPA. EJB+JPA can be used to implement DAOs.
Arjan Tijms has put together a nice link overview of what is included and happening in the java-ee-7 world

Categories

Resources