12 Replies Latest reply: Apr 22, 2011 7:31 PM by henk de boer RSS

Using an EJB inside a JAX-RS resource class in RestEasy?

henk de boer Master

I wonder if it's already possible to inject an EJB in a JAX-RS resource class in JBoss AS 6.

 

For instance, suppose I have the following class:

 

 

@Path("Something")
public class Foo {

  @EJB
  private SomeService service

  @GET
  public Object frobnicate() {
    assert service != null;
    // JBoss blows up here

    return result;
  }
}

 

(Example taken from http://stackoverflow.com/questions/3025739/using-an-ejb-inside-a-jax-rs-resource-class-in-resteasy)

 

How can I make this work?

 

I tried to make the resource an EJB (as suggested by Adam Bien in http://www.adam-bien.com/roller/abien/entry/ejb_3_1_and_rest), but this blows up with the following exception:

 

 

Caused by: javax.naming.NameNotFoundException: local not bound
          at org.jnp.server.NamingServer.getBinding(NamingServer.java:771) [:5.0.5.Final]
          at org.jnp.server.NamingServer.getBinding(NamingServer.java:779) [:5.0.5.Final]
          at org.jnp.server.NamingServer.getObject(NamingServer.java:785) [:5.0.5.Final]
          at org.jnp.server.NamingServer.lookup(NamingServer.java:443) [:5.0.5.Final]
          at org.jnp.server.NamingServer.lookup(NamingServer.java:399) [:5.0.5.Final]
          at org.jnp.server.NamingServer.lookup(NamingServer.java:399) [:5.0.5.Final]
          at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:728) [:5.0.5.Final]
          at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:688) [:5.0.5.Final]
          at javax.naming.InitialContext.lookup(InitialContext.java:392) [:1.6.0_20]
          at org.jboss.resteasy.plugins.server.resourcefactory.JndiComponentResourceFactory.createResource(JndiComponentResourceFactory.java:53) [:6.0.0.Final]
          ... 29 more

 

Any ideas?

  • 1. Using an EJB inside a JAX-RS resource class in RestEasy?
    jaikiran pai Master

    What's SomeService? A no-interface view bean?

  • 2. Using an EJB inside a JAX-RS resource class in RestEasy?
    henk de boer Master

    jaikiran pai wrote:

     

    What's SomeService? A no-interface view bean?

     

    I used it as an example for any kind of EJB and any kind of view, although in my specific test-case I tried a local interface for a stateless session bean. It simply remained null (so no injection happened).

     

    In the test where I annotated Foo with @Stateless (as per Adam Bien's suggestion), I did not create a local interface though and I indeed relied on the no-interface view.

  • 3. Re: Using an EJB inside a JAX-RS resource class in RestEasy?
    henk de boer Master

    As it appears, the hack that was required for earlier versions is still needed, but using that it does sort of work. It concerns this:

     

    <context-param>      
        <param-name>resteasy.jndi.resources</param-name>      
        <param-value>LibraryBean/local</param-value>   
    </context-param>
    
    
    

    See: http://docs.jboss.org/resteasy/docs/2.0.0.GA/userguide/html/RESTEasy_EJB_Integration.html

     

    Using this thus works, but it does require me to move my combined JAX-RS resource/Stateless session bean from the war module to an ejb module. Apparently RestEasy tries to resolve the JNDI reference before all EJB beans in the war module are bound. It then craps out with the following exception:

     

     

    23:30:03,646 ERROR [[/restful]] Exception starting filter Resteasy: java.lang.RuntimeException: javax.naming.NameNotFoundException: TestResource not bound
    [...]
    Caused by: javax.naming.NameNotFoundException: TestResource not bound
              at org.jnp.server.NamingServer.getBinding(NamingServer.java:771) [:5.0.5.Final]
              at org.jnp.server.NamingServer.getBinding(NamingServer.java:779) [:5.0.5.Final]
              at org.jnp.server.NamingServer.getObject(NamingServer.java:785) [:5.0.5.Final]
              at org.jnp.server.NamingServer.lookup(NamingServer.java:396) [:5.0.5.Final]
              at org.jnp.server.NamingServer.lookup(NamingServer.java:399) [:5.0.5.Final]
              at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:728) [:5.0.5.Final]
              at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:688) [:5.0.5.Final]
              at javax.naming.InitialContext.lookup(InitialContext.java:392) [:1.6.0_20]
              at org.jboss.resteasy.plugins.server.resourcefactory.JndiResourceFactory.getScannableClass(JndiResourceFactory.java:57) [:6.0.0.Final]
    
    

     

    A little while the EJB is bound, but then it's too late:

     

     

    23:30:03,695 WARN  [TimerServiceContainer] EJBTHREE-2193: using deprecated TimerServiceFactory for restoring timers
    23:30:03,697 INFO  [AbstractNoInterfaceViewBinder] Binding the following entry in Global JNDI for bean:TestResource
    
              test_rest/TestResource/no-interface -> EJB3.1 no-interface view
    
    

     

    So again, with the web.xml hack and moving my beans to a separate EJB module I now do have it working, but it's not exactly elegant.

     

    Now Java EE 6 is really becoming a very elegant platform and JBoss AS is one of the forerunners here, so I hope this little inconvenience can be resolved. Are there any plans for this?

  • 5. Re: Using an EJB inside a JAX-RS resource class in RestEasy?
    henk de boer Master

    jaikiran pai wrote:

     

    See http://community.jboss.org/thread/160710

     

    Thanks, I take it the reference is for the information on how to remove the need for moving the combined resource/session beans to an EJB module, right?

     

    So for other people reading this discussion, it's the following line in jboss-web.xml:

     

    <depends>jboss.j2ee:ear=your.ear,jar=yourejb.jar,name=yourejbname,service=EJB3</depends>
    

     

     

    I think I will actually use this solution, but from an "elegancy" point of view it's not the best thing. Where I expected I needed only an annotation, I now have to list every bean in 2 different XML files. The Spring fans in my company are going to make fun of me beyond belief when they spot this code

  • 6. Re: Using an EJB inside a JAX-RS resource class in RestEasy?
    henk de boer Master

    henk de boer wrote:

     

    <depends>jboss.j2ee:ear=your.ear,jar=yourejb.jar,name=yourejbname,service=EJB3</depends>

     

    On second thoughts, this of course implies that the beans are in a separate EJB module.

     

    In this case the problem is that the RestEasy filter in the web module kicks in before the EJB beans, which are also in the web module, are bound to JNDI.

     

    So what is needed is a way to express dependencies within the web module.

  • 7. Re: Using an EJB inside a JAX-RS resource class in RestEasy?
    henk de boer Master

    I'm also wondering whether I'm still not doing something wrong. I found the following comment from Bill Burke on his blog for the RestEasy 2.0 release notes:

     

    The upcoming JBoss AS 6-Milestone 4 release will also have deeper integration with RESTEasy so that you can do automatic scanning, EJB injection, CDI injection, etc.  All the stuff you’d expect from a JAX-RS integrated EE 6 solution.

    see: http://bill.burkecentral.com/2010/07/19/resteasy-2-0-0-released/

     

    Yet the manual contradicts this by talking about the necessity to enter the JNDI names in web.xml, but maybe the manual is JBoss AS agnostic and just talks about the general case.

     

    Can anyone confirm whether or nor EJB injection should "just work" in JAX-RS resources in JBoss AS 6?

  • 8. Using an EJB inside a JAX-RS resource class in RestEasy?
    Michael Brackx Newbie

    Can anyone confirm whether or nor EJB injection should "just work" in JAX-RS resources in JBoss AS 6?

    Without web config EJB injection works if your resource is a CDI bean in the war.

    I don't know what should work.

  • 9. Using an EJB inside a JAX-RS resource class in RestEasy?
    henk de boer Master

    Michael Brackx wrote:

     

    Can anyone confirm whether or nor EJB injection should "just work" in JAX-RS resources in JBoss AS 6?

    Without web config EJB injection works if your resource is a CDI bean in the war.

    I don't know what should work.

     

    Yes, after studying various sources I found that if the JAX-RS resource is also a CDI bean (or technically, enhanced by CDI), then injecting EJBs should work via the @Inject annotation. If the JAX-RS resource is also an EJB bean, then injection via @EJB works.

     

    However, injection via either @Inject or @EJB does not work in plain JAX-RS resources. In that case only injection via @Context works.

     

    If the JAX-RS resource is an EJB but not CDI enhanced, then @Context doesn't work. I'm not 100% sure whether this is spec compliant or a bug in JBoss.

     

    Furthermore, in JBoss AS 6, only EJBs that are defined in the same web module as the JAX-RS resource can be injected. This is definitely not spec compliant and a huge bug in JBoss AS.

  • 10. Using an EJB inside a JAX-RS resource class in RestEasy?
    jaikiran pai Master

    henk de boer wrote:

     


    Furthermore, in JBoss AS 6, only EJBs that are defined in the same web module as the JAX-RS resource can be injected. This is definitely not spec compliant and a huge bug in JBoss AS.

    Do we have a JIRA with details and maybe a sample application, for that one?

  • 11. Using an EJB inside a JAX-RS resource class in RestEasy?
    Shelly McGowan Apprentice

    When filing the JIRA, please include the spec reference that you're referring to.

  • 12. Using an EJB inside a JAX-RS resource class in RestEasy?
    henk de boer Master

    jaikiran pai wrote:

     

    Do we have a JIRA with details and maybe a sample application, for that one?

     

    There's a JIRA here with steps to reproduce: https://issues.jboss.org/browse/WELD-889

     

    The problem doesn't just concern injection of EJB beans, but seems to be part of a bigger problem: https://issues.jboss.org/browse/AS7-623

     

    Jan Groth also found several other issues to be related:

     

     

    Specifically about the extensions case, Marius has indicated it's dependent on this one: https://issues.jboss.org/browse/WELD-778