How to inject an EJB into an @WebService in a WAR that is separate from the deployment containing the EJB in JBoss EAP 5?

Solution Verified - Updated -

Environment

  • JBoss Enterprise Application Platform (EAP)
    • 5.x

Issue

  • An @WebService is defined in a WAR and registered as a servlet in web.xml. The @WebService has an @Resource dependency on an EJB that is defined in a different deployment. When accessing the web service, an exception with Cause by elements like the following is thrown:
...
Caused by: org.jboss.wsf.common.injection.InjectionException: Cannot inject field annotated with @Resource annotation: private com.example.test.SimpleSLSBRemote test.SimpleManagerPortTypeImpl.SimpleRemote
        at org.jboss.wsf.common.injection.InjectionException.rethrow(InjectionException.java:106)
        at org.jboss.wsf.common.injection.InjectionHelper.injectResourceAnnotatedAccessibleObjects(InjectionHelper.java:295)
        at org.jboss.wsf.common.injection.InjectionHelper.injectResources(InjectionHelper.java:110)
        at org.jboss.wsf.container.jboss50.invocation.InvocationHandlerJSE.getTargetBean(InvocationHandlerJSE.java:93)
        at org.jboss.wsf.container.jboss50.invocation.InvocationHandlerJSE.invoke(InvocationHandlerJSE.java:110)
        at org.jboss.wsf.stack.cxf.AbstractInvoker._invokeInternal(AbstractInvoker.java:154)
        ... 40 more
Caused by: org.jboss.wsf.common.injection.InjectionException: Resource 'SimpleBean' not found
        at org.jboss.wsf.common.injection.InjectionException.rethrow(InjectionException.java:106)
        at org.jboss.wsf.common.injection.InjectionHelper.lookup(InjectionHelper.java:409)
        at org.jboss.wsf.common.injection.InjectionHelper.inject(InjectionHelper.java:387)
        at org.jboss.wsf.common.injection.InjectionHelper.injectResourceAnnotatedAccessibleObjects(InjectionHelper.java:290)
        ... 44 more
Caused by: javax.naming.NameNotFoundException: SimpleBean not bound
        at org.jnp.server.NamingServer.getBinding(NamingServer.java:771)
        at org.jnp.server.NamingServer.getBinding(NamingServer.java:779)
        at org.jnp.server.NamingServer.getObject(NamingServer.java:785)
        at org.jnp.server.NamingServer.lookup(NamingServer.java:443)
        at org.jnp.server.NamingServer.lookup(NamingServer.java:399)
        at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:750)
        at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:710)
        at org.jboss.wsf.common.injection.InjectionHelper.lookup(InjectionHelper.java:404)
        ... 46 more

Resolution

  • Injection with @Resource(name="<name>") works if using EJB references in web.xml to tie the global JNDI name of the EJB to the web apps ENC.
<?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_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>SimpleWebServiceWAR</display-name>
  <servlet>
    <display-name>SimpleWebService</display-name>
    <servlet-name>SimpleWebService</servlet-name>
    <servlet-class>jboss.example.SimpleWebService</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>SimpleWebService</servlet-name>
    <url-pattern>/SimpleWebService</url-pattern>
  </servlet-mapping>
  <ejb-local-ref>

    <!-- name to reference in @Resource(name="SimpleSLSB") -->
    <ejb-ref-name>SimpleSLSB</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>

    <!-- name bound in global JNDI (or given as mappedName on the EJB)
    <mapped-name>SimpleEAR/SimpleSLSB/local</mapped-name>
  </ejb-local-ref>
</web-app>
  • or for remote reference:
<?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_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>SimpleWebServiceWAR</display-name>
  <servlet>
    <display-name>SimpleWebService</display-name>
    <servlet-name>SimpleWebService</servlet-name>
    <servlet-class>jboss.example.SimpleWebService</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>SimpleWebService</servlet-name>
    <url-pattern>/SimpleWebService</url-pattern>
  </servlet-mapping>
  <ejb-ref>
    <ejb-ref-name>SimpleSLSB</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>
    <mapped-name>SimpleEAR/SimpleSLSB/remote</mapped-name>
  </ejb-ref>
</web-app>

Root Cause

  • The injection handling code in the web services stack ignores the mappedName attribute of @Resource and can't find EJBs via the @EJB annotation if they're defined in a different deployment. However, the name element of @Resource looks in the component's ENC.

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.

Close

Welcome! Check out the Getting Started with Red Hat page for quick tours and guides for common tasks.