12 Replies Latest reply on Apr 22, 2011 7:31 PM by henk53

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

    henk53

      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

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

          • 2. Using an EJB inside a JAX-RS resource class in RestEasy?
            henk53

            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?
              henk53

              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?

              • 4. Re: Using an EJB inside a JAX-RS resource class in RestEasy?
                jaikiran
                • 5. Re: Using an EJB inside a JAX-RS resource class in RestEasy?
                  henk53

                  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?
                    henk53

                    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?
                      henk53

                      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?
                        brackxm

                        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?
                          henk53

                          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

                            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

                              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?
                                henk53

                                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