10 Replies Latest reply on May 5, 2009 1:37 AM by allanjun

    Using @EJB to inject an EJB into a component

    arsenalist

      Is this even possible?



      @Stateless
      public class MyEjbBean implements MyEjb {
         . . . .
      }
      
      @Name("myComponent")
      public class MyComponent {
         
         @EJB
         private MyEjb myEjb;
        
         . . . 
      
      }




      I tried using the @In annotation like the following but the bean never gets injected:




      @Name("myComponent")
      public class MyComponent {
         
         @In(create=true)
         private MyEjb myEjb;
        
         public String doSomething() {
             // myEjb is null
         }
      
      }
      



      Any ideas about how I get an EJB injected into a component?


      Any help would be appreciated.

        • 1. Re: Using @EJB to inject an EJB into a component
          enda

          Well I am getting into a similar problem. Do we have to implement @Factory for this or do we have to specify the component in Components.xml?


          Something similar to this here

          • 2. Re: Using @EJB to inject an EJB into a component
            arsenalist

            This is kinda like the blind leading the blind here but I think the component is registered fine. I can see in the logs that myComponent is registered.


            The EJB is also registered as I have a simple servlet that uses it and the @EJB annotation works fine over there, so both objects do exist.  It's a question of having Seam inject the EJBs into the components.


            If anybody has a solution or a workaround, I'd be very happy to hear it.  Thanks in advance.

            • 3. Re: Using @EJB to inject an EJB into a component
              dahm

              Your session bean has no @Name tag so it cannot possibly work, since Seam doesn't know this class then.


              So give it a name und use it in the @In tag.


              Cheers
                Markus

              • 4. Re: Using @EJB to inject an EJB into a component
                arsenalist

                Thanks for the reply Markus.


                I tried that and put a @Name(myEjb) annotation on the SLSB and used @In instead of @EJB but got this error:


                org.jboss.seam.RequiredException: @In attribute requires non-null value: myComponent.myEjb


                If I try using @In(required=false), myEjb never gets injected.


                If I try  using @In(required=false, create=true), I get the following error:


                javax.servlet.ServletException: #{myComponent.myComponentMethod}: org.jboss.seam.InstantiationException: Could not instantiate Seam component: myEjb


                and the cause of the exception is:


                javax.naming.NameNotFoundException


                This doesn't make any sense because in the logs I see this:


                Component: myEjb, scope: CONVERSATION, type: STATELESSSESSIONBEAN, class: com.mypackage.MyEjbBean, JNDI: MyEjbBean/local


                For what its worth I've also tried this using the SeamInterceptor by annotating the component with @Stateless(SeamInterceptor.class) and by specifying the following property in web.xml:



                    <context-param>
                        <param-name>org.jboss.seam.core.init.jndiPattern</param-name>
                        <param-value>#{ejbName}/local</param-value>
                    </context-param>



                I've also tried the following but with no success:



                @In(required=false, value="myEjb")
                @In(required=false, value="#{myEjb}")
                @In(required=false, create=true, value="myEjb")
                @In(required=false, create=true, value="#{myEjb}")




                The only thing odd worth mentioning is that the EJB and the Seam component are in two different JARs but that shouldn't matter since I see both of them getting registered with Seam in the logs.  Is this a JNDI issue because only the SLSB has a jndi name associated with it, not the plain old Seam components.


                I've even consulted two books called Beginning JBoss Seam and Practical JBoss Seam and they have no mention of this seemingly simple scenario.


                All I'm trying to do is separate my action layer which consists of Seam components from my DAO layer which consists of beans that are Seam components and EJBs.


                Any help is greatly appreciated.

                • 5. Re: Using @EJB to inject an EJB into a component
                  dahm

                  Well, I'm not sure whether this scenario is really supported by Seam, since EJB's normally are obtained via JNDI.


                  The simplest solution is clear: Make MyComponent a session bean.
                  This is not costly as of EJB 3.0.


                  If that is not feasible you always can perform a JNDI lookup


                  new InitialContext().lookup(MyEJB.JNDI_NAME);
                  


                  or use


                  @JndiInject
                  

                  from jboss annotations:


                  @JndiInject(name="pathTo-MyEjbBean/local")
                  private MyEjb myEjb;
                  



                  Cheers
                     Markus

                  • 6. Re: Using @EJB to inject an EJB into a component

                    It is very possible this is a JNDI issue.  Check components.xml for your configured jndi-pattern and make sure it matches how your EJB is being registered:


                    <core:init jndi-pattern="#{ejbName}/local"/>



                    Also, for what it is worth if you want the EJB created there is another option.  Simply annotate the EJB with @AutoCreate and you can leave out the create=true in the @In.


                    Hope it helps.

                    • 7. Re: Using @EJB to inject an EJB into a component
                      arsenalist

                      Thanks for the suggestion.  I have the JNDI pattern configured via a web.xml init parameter and its not the problem.  I also tried putting it in the components.xml but that didn't work either. 

                      • 8. Re: Using @EJB to inject an EJB into a component
                        arsenalist

                        Jacob, I'm using Glassfish so @JndiInject doesn't apply to me. 


                        This problem is leading me to a deeper question:


                        How does one separate the action layer from the DAO layer in Seam? In my action layer (which I hoped to be purely Seam components) I wanted to redirect to views, provide success/fail messages and do some manual validation etc. and once done, I would make calls to my EJB layer (which I hoped to be EJB beans and Seam components).


                        Any recommendations on how to do this?


                        Thanks.

                        • 9. Re: Using @EJB to inject an EJB into a component
                          arsenalist

                          BTW, the problem with this whole setup was me not defining an <ejb-local-ref> element for the EJB in web.xml.  That fixed everything:


                          <ejb-local-ref>
                             <ejb-ref-name>MyEjbBean</ejb-ref-name>
                             <ejb-ref-type>Session</ejb-ref-type>
                             <local>MyEjb</local>
                          </ejb-local-ref>


                          • 10. Re: Using @EJB to inject an EJB into a component
                            allanjun

                            This doesn't seem to be working with JBoss, anyone knows how to solve this problem with JBoss 5?