How to inject an EJB into an @WebService in a WAR that is separate from the deployment containing the EJB in JBoss EAP 5?
Environment
- JBoss Enterprise Application Platform (EAP)
- 5.x
Issue
- An
@WebServiceis defined in a WAR and registered as a servlet inweb.xml. The@WebServicehas an@Resourcedependency on an EJB that is defined in a different deployment. When accessing the web service, an exception withCause byelements 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 inweb.xmlto 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
mappedNameattribute of@Resourceand can't find EJBs via the@EJBannotation if they're defined in a different deployment. However, thenameelement of@Resourcelooks 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.
Welcome! Check out the Getting Started with Red Hat page for quick tours and guides for common tasks.
