How come injection #Resource works outside the container? - java

I'm testing webservices in Java SE, and I see that #Resource does work, wasn't this true only within a Container ? or with CDI ? why does it work in SE also !?
#WebService
public class Teams {
#Resource
private WebServiceContext context;
}
I'm publishing using Endpoint.publish("http://localhost:9876/teams", new Teams());

Not true. Container will inject the instance of the resource on any EJB component.
http://docs.oracle.com/javaee/5/api/javax/annotation/Resource.html

Related

JNDI #Resource annotation

In servlet and filter classes i can initialize DataSource variable via annotation
#Resource(name = "jdbc/testDB")
protected DataSource ds;
But how it initialize in basic class via annotation?
Usually thorows NullPointerException
public class AddAuto {
#Resource(name = "jdbc/testDB")
private DataSource ds;
}
What is your container?
If it's tomcat, the resource name should be something like this
#Resource(name = "java:/comp/env/jdbc/testDB")
protected DataSource ds;
I don't know about the other container, but JBoss would be same as Tomcat, and GlassFish as your value.
Also I suggest old lookup which help you so much for debugging
void init(){
DataSource ds=(DataSource)InitialContext.doLookup("java:/comp/env/jdbc/testDB");
}
Container inspects annotation only inside well-known componets like servlets, filters. You should transform your class to some component:
Web component (servlet, filters, web container listeners)
EJB (not supported by tomcat)
CDI beans
Or you can use non Java EE solution like spring

Atmosphere #ManagedService #Inject not working

I have no idea, but my #Inject objects are not initialized with Weld inside of the ManagedService, my example is like this,
#ManagedService(path = "/chat") public class EntryPointWS {
private final Logger logger = LoggerFactory.getLogger(EntryPointWS.class);
#Inject private ServiceFactory factory;
}
The same project or code, If i use a normal Servlet to access Weld will initialize the objects for me. Also, I'm running on Tomcat 8, it works fine with the Servlet injection though. Also, ServiceFactory is annotated as #ApplicationScoped.
Just to be clear, to add some more points,
org.atmosphere.cdi.CDIObjectFactory (from the cdi pom) is defined in
The #Inject doesn't work in AtmosphereInterceptorServices as well.
have you enabled the CDI extension : https://github.com/Atmosphere/atmosphere/wiki/Configuring-Atmosphere's-Classes-Creation-and-Injection
-- Jeanfrancois

Use WebServiceContext outside WebService

In my Web service, I have:
#WebService(serviceName = "myservice")
public class ServiceName{
#Resource
private WebServiceContext context;
In a stateless class I want to use the same operation:
#Stateless
public class MakeHappen{
#Resource
private WebServiceContext context;
But I receive an EJB exception. How can I inject this resource, outside webservice?
AFAIK no, only in the context of a Webservice.
See Interface WebServiceContext
A WebServiceContext makes it possible for a Webservice endpoint
implementation class to access message context and security
information relative to a request being served. Typically a
WebServiceContext is injected into an endpoint implementation class
using the #Resource annotation.
In your case, you should to decorate stateless EJB as Webservice. Open methods of the stateless EJB can be represented as Webservices.
#Stateless
#WebService
public class MakeHappen {
#Resource
private WebServiceContext context;
...
Web service endpoint belongs to a web tier and is managed by a web container (See Java EE 7 tutorial 6.1 Web Applications for more info).
Enterprise bean on the other hand is a business logic component. It is managed by EJB container (Java EE 7 tutorial 32.1 What Is an Enterprise Bean?).
This means that enterprise bean could not have WebServiceContext injected as it is managed by different container. This would also make no sense as EJB container have no WebServiceContext.
I had the same problem and this is how I solved it:
WebServiceContext wscontext = null;
try {
Context ctx = new InitialContext();
wscontext = (WebServiceContext) ctx.lookup("java:comp/WebServiceContext");
} catch (NamingException e) {
}

Why Initialization is not required in EJB?

I am new to the Struts2 framework and to EJB as well. I have a class LoginDAO which implements checkUser method of an interface LoginDAOLocal. I don't understand why I see different behavior for the following scenarios:
If I use an EJB (LoginDAO is stateless session bean) as follows, method call works perfectly without any error.
#EJB
private LoginDAOLocal loginDao;
loginDao.checkUser(userName,password);
If I use Struts2 as follows, it gives a Null pointer exception for the method call.
public class LoginAction extends ActionSupport {
// Getters setters for userName and password)
private LoginDAOLocal loginDao;
loginDao.checkUser(this.userName,this.password);
}
If I use a simple Java application (no EJB or Struts2), the method call creates a compile time error saying loginDao is not initialized
public static void main(String[] args) {
LoginDAOLocal loginDao;
loginDao.checkUser(userName,password);
}
Can someone explain why this different behavior ?
Without getting too much into the Java EE spec: EJBs are managed by an EJB container that exists in J2EE servers (JBoss \ Websphere etc..). The container takes control of bean lifecycle and is responsible for creating \ destroying beans according to the application needs.
When running out of container (simple java application) your beans won't get initialized and you don't have a JNDI context to get beans from, even if you add #EJB annotation to the field member.
We can say that there are two ways to manage the beans, using the container (managed by the container), or by another component (managed by a servlet, listener or filter).
Using components managed by the container, the container injects the references. e.g.:
#WebServlet("/test")
public class MyServlet extends HttpServlet {
#Resource(lookup = "jdbc/TestDS")
private DataSource testDS;
}
By contrast, a component managed by a bean, e.g.:
#Namespace("/User")
#ResultPath(value = "/")
#Result(name = "success", location = "pages/login.jsp")
public class LoginAction extends ActionSupport {
}
is managed by the filter org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter. The latter should be responsible for performing dependency injection. Spring, for example, takes care of injecting all necessary dependencies.

CDI Injection of an EJB leads to NullPointerException

I am new to Java EE 6 and CDI. I have read a couple of tutorials and the weld documentation. However something that should work from my understanding doesn't so I need help.
I have the following situation. I created a Java EE 6 Application with NetBeans 7.0.1 using the maven archetype supplied with the IDE and I deploy to GlassFish 3.1 also supplied by the IDE.
The beans.xml is located in the META-INF directory of my EJB jar.
I have created a class that works soley as a producer class for my EJB Artifacts (and EntityManager)
#Stateless
public class EjbArtifactProducer {
#PersistenceContext(unitName = "trackProfiler-PU")
private EntityManager em;
#EJB
private UserFacadeLocal userFacade;
#EJB
private AuthServiceLocal authService;
#EJB
private NewsEntryFacadeLocal newsEntryFacade;
#EJB
private RoleFacadeLocal roleFacade;
#EJB
private TrackCommentFacade trackCommentFacade;
#EJB
private TrackFacade trackFacade;
#EJB
private TrackTypeFacade trackTypeFacade;
#EJB
private WaypointFacadeLocal waypointFacade;
#Produces
public AuthServiceLocal getAuthService() {
return authService;
}
#Produces
public EntityManager getEm() {
return em;
}
#Produces
public NewsEntryFacadeLocal getNewsEntryFacade() {
return newsEntryFacade;
}
#Produces
public RoleFacadeLocal getRoleFacade() {
return roleFacade;
}
#Produces
public TrackCommentFacade getTrackCommentFacade() {
return trackCommentFacade;
}
#Produces
public TrackFacade getTrackFacade() {
return trackFacade;
}
#Produces
public TrackTypeFacade getTrackTypeFacade() {
return trackTypeFacade;
}
#Produces
public UserFacadeLocal getUserFacade() {
return userFacade;
}
#Produces
public WaypointFacadeLocal getWaypointFacade() {
return waypointFacade;
}
}
I tried to apply the #Produces annotation directly to the fields an on methods as shown above.
However the following does not inject anything in another EJB
#Inject
private NewsEntryFacadeLocal newsEntryFacade;
This is done in a stateless session ejb but when I try to access newsEntryFacade in any of my business methods a NullPointerException is thrown. So clearly no Injection is happening or my producers produce null references.
Am I missing something? Or should this work according to CDI/Weld?
Strangely it seems to work that way when I try to #Inject EJBs into the web application part (however i needed an extra producer class in my .war for this to work, is this as it should be?).
EDIT: The project works with an ant build (generated by NetBeans). Are there issues with the Maven archetype provided by NetBeans? It seems that with the Maven archetype there are some issues with CDI injection between the war and ejb modules. I found that if I had separate producers in the web and ejb module Glassfish generates a deployment error stating that there are two indistinguishable implementations of an interface. But when I remove the producer in the web module Weld complains that the EJB i want to inject into my beans in the web module cannot be resolved. Also with the Ant build EJBs can be #Injected without a producer while the maven build needs producer fields on a class. I can't explain how this could happen. After all the final deployment should be more or less equal, shouldn't it?
If you want to use #Inject then annotate it as #Named #ApplicationScoped, otherwise use #EJB when injecting your singleton.
Jordan Denison is correct. You're trying to #Inject and EJB, but you be using #EJB for EJBs. You're EJB class is probably annotated with #Stateless or something. #Inject should be used on session beans that annotated with #Named and some sort of scope.
Hard to tell whats going wrong but what definitely did not work for us is to use CDI between class loader boundaries. For example if your application is packaged as an ear file you would have your ejbs in an jar file and your webapp in your war file. In this case you can not use CDI to inject your ejbs in your web layer. The problem is that the jar and the war is loaded by different class loaders. Maybe newer CDI implementations behave different but at least JBoss 6 and Glassfish had this problem.
Try to put #Named into EjbArtifactProducer. Also, if the produces is this kind of simple, I think it's better to remove it too (else, you should do one more change).
you are mixing two different concepts... use CDI as backing beans for JSF. (CDI in Web Container) and use EJB and JPA in the Business Layer... the CDI layer can inject a EJB to call the specific business method.
in this case you have a clean separation on concerns.
BTW: you do not need any EJB interfaces at all! use only interfaces if you have a requirements to communicate from remote... (#Remote). with the #LocalBean annotation you can inject directly the EJB itself..
if you have e clean separation of layers each with his own concern i think you better find the reason for this NullPointerException.. and i think your NullPointerException does not exists any more after this...
Layering:
Web Browser --> JSF Facelet --> CDI Backing Bean --> EJB Service(s) --> EntityManager

Categories

Resources