Reputation: 1069
I have a Maven project in Eclipse that is deployed as an EAR containing a JAR module (Java 1.7, EJB 3.1 and JPA 2.0 project) and a WAR module (Servlet 3.0, Java 1.7, JAX-RS 1.1). I am deploying it to a Weblogic 12.1.1.0. The structure is as follows:
backoffice-ear
backoffice-ejb-core-0.0.1-SNAPSHOT.jar
backoffice-ws-0.0.1-SNAPSHOT.war
The WS project has classes that implement REST web services that call the Services and Data Access Objects defined as Stateless EJB in the EJB project. Here's an example:
WAR:
@Path("/Events")
@Stateless
public class EventsWS {
@EJB
private EventsService eventsService;
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/searchEvents")
public Response searchEvents() {
eventsService.searchEvents(null, "S", "TEST", new BigDecimal(1), new BigDecimal(20));
...
}
}
JAR:
@Stateless
public class EventsService {
@EJB
private EventsDao dao;
public DtoSearchEvents searchEvents(...) throws ServiceException {
...
}
}
The injections work fine inside the JAR module. But between the WAR and JAR they don't.
What happens here is that the injected EJB service in EventsWS
is always null. But if I load it through JNDI, I am able to use it correctly:
Context context = new InitialContext();
eventsService = (EventsService)context.lookup("java:global/backoffice-ear/backoffice-ejb-core-0.0.1-SNAPSHOT/EventsService");
But I want to be able to inject the EJB without loading it through JNDI. I already tried using @EJB's mappedName
attribute with the JDNI path mentioned above but without success. I suppose I am using the correct JNDI path. What am I missing? Let me know if you need more info.
My web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>backoffice-ws</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>backoffice-ws-servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>xxx.yyy.zzz.backoffice.ws</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>backoffice-ws-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Upvotes: 0
Views: 1847
Reputation: 2893
Your EventWS
is annotated with @Stateless
, although it is in the WAR module. What happens is that your @Stateless
annotation is ignored (since it's in the WAR), and your EventWS
bean is not managed, thus no values are injected.
You need to make the EventWS
a managed CDI bean (for example, @RequestScoped
). You may want to show the remaining config (web.xml
and the JAX-RS annotations that you ommitted) for further help.
Update to answer the question in the comment:
Your are using a non-standard servlet definition. I don't know whether the jersey servlet respects the CDI annotations, therefore you might want to try this in web.xml
instead:
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
(or subclass javax.ws.rs.core.Application
with the @ApplicationPath
annotation. See the Java EE 7 Tutorial for details.)
And then don't for get to annotate your EventWS
with @RequestScoped
or @SessionScoped
or whatever fits your needs.
Upvotes: 0