0

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>
Baderous
  • 1,069
  • 1
  • 11
  • 32

1 Answers1

0

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.

Alexander Langer
  • 2,883
  • 16
  • 18
  • Why does @Stateless annotation is ignored in WAR? – Sri Sep 30 '14 at 05:13
  • I updated my post to include JAX-RS annotations and web.xml. How can I make EventsWS a CDI bean? What annotations and xml config files do I need (beans.xml?)? – Baderous Sep 30 '14 at 08:12
  • 1
    @Sriram because in an EAR application, the EJB beans are to be deployed in an EJB module. – Alexander Langer Sep 30 '14 at 12:07
  • I am still struggling with this problem. I created a subclass of ``Applcation`` with ``@ApplicationPath("rest/")``, commented all my web.xml, removed ``@Stateless`` from EventsWS and added ``@RequestScoped`` and I still get the error. – Baderous Oct 02 '14 at 12:07
  • can you post a minimal (non-)working code example? Did you include a `beans.xml`? – Alexander Langer Oct 02 '14 at 12:25
  • Yes, I included a beans.xml inside my WEB-INF folder with no explicit bean declaration, just the open/close tags and namespaces. Here is some sample code not working: http://pastebin.com/vL8jhCQJ Let me know if you need more info. – Baderous Oct 02 '14 at 14:25
  • pasting some random code to pastebin does not really help when the directory structure is important. This should really work, even without the `@RequestScoped` annotation, see this small sample project, which works flawlessly on JBoss 7.1.1: https://github.com/lngr/WebServiceTest – Alexander Langer Oct 02 '14 at 21:15
  • @Alexander Langer - untrue. you can still use "simplified packaging" inside an EAR file. the only thing the EAR file changes is the enclosing classloader, deployment context, and jndi semantics. – him Sep 17 '18 at 03:20