12 Replies Latest reply on Mar 9, 2010 6:29 AM by Arbi Sookazian

    injection of existing ejb

    Matthieu Guyonnet-Duluc Newbie

      Hello,


      I would like to use existing EJBs (stateless remote) in my seam project. I use the @ejb annotation but the ejb is always null.


      I have added the jndi pattern in the components.xml. Here's an example of a seam bean :



      @Name("authenticator")
      public class AuthenticatorBean
      {
          @EJB
          private ServiceMEN service;
          (...)
      }





      I got a NullPointerException but no injection error etc....


      My project :


      - MyProject.ear
         + MyWebApp.war (with seam components)
         + MyEJB.jar (Stateless EJB)






        • 1. Re: injection of existing ejb
          Matthieu Guyonnet-Duluc Newbie

          and my web.xml



          <ejb-ref>
                 <ejb-ref-name>service</ejb-ref-name>
                 <ejb-ref-type>Session</ejb-ref-type>
                 <home>com.blabla.IService</home>
                 <remote>com.blabla.IService</remote>
          </ejb-ref>




          jboss-web.xml



          <ejb-ref>
             <ejb-ref-name>service</ejb-ref-name>
             <jndi-name>MyProject/ServiceBean/remote</jndi-name>
          </ejb-ref>



          components.xml



          <core:init debug="true" jndi-pattern="MyProject/#{ejbName}/remote" />




          Matthieu

          • 2. Re: injection of existing ejb
            Jacques Lemire Newbie

            I have been trying to do just that and was quite surprised not to be able to find more information on the subject.


            I am working on an application where the ejb model that is not seam-enabled, but exposes services to a seem web application. In that context, we saw little sense to make the seam components ejbs, so we are deploying the web-app as a war, with the jsf backed by seam POJOs. Both the seam-enabled WAR and non-seam JARs are packed in an EAR. It looks quite similar to your setup, except that we are using an ejb client jar for the interfaces and entities.


            As I read everywhere, JBoss 5 supports @EJB injection on managed components in a war. I have read reports of this feature working both for servlets and jsf backing POJOs. However, I don't have anymore success than you getting that to work with seam-managed backing beans. No matter what I configure in web.xml, the injection does not happen as I would expect and the member stays null. I did not have the time yet to read through the seam source code, but I am wondering if the real managed JSF backing bean under the hood could be an internal seam component that delegates the calls to our seam POJO, hence making it impossible for the web container to do the injection.


            If you ever get this to work, I would be really interested if you let us know how you succeeded. In my case, I decided to write a seam-managed application-scoped ServiceFactory that exposes @Factory methods, each of which locates the requested session facade through JNDI and outjects it to the context. In fact, only one generic method takes care of the lookup, and factory methods call it by passing the interface class and jndi name. Seam actions can then inject it the usual way:


            @In( required=true ) 
            UserManager userManager;
            



            Jacques

            • 3. Re: injection of existing ejb
              Jason Jiang Newbie

              Don't Anyone in Seam team can give us a perfect solution to such a problem, it should be common requirement for enterprise application

              • 4. Re: injection of existing ejb
                Jason Jiang Newbie

                Could Seam Team give a perfect solution so we can follow it

                • 5. Re: injection of existing ejb
                  Stuart Douglas Master

                  @EJB is part of the EJB spec, not the seam spec. You can only use it inside other EJB's. In the OP's example it is being used in a POJO seam component, which will not work.

                  • 6. Re: injection of existing ejb
                    Larry Ozo Newbie

                    My solution - I use an JNDI lookup. But it is  so exhausting work. Standart jsf bean implementation allows me to use @EJB injection insie jsf beans, but Seam beans - doesn't. Using @EJB  for enterprise application is very actual requirement

                    • 7. Re: injection of existing ejb
                      Arnie Morein Newbie
                      I second this motion!

                      After dabbling with Seam I was all excited to get busy writing Seam-based Portlets using EJB3.

                      Imagine my surprise when I found out that all the domain beans and stateless DAOs in the EJB JARs would have to be bound together into each Seam portlet EAR in order to be utilized as a Seam bean.

                      Exactly what would be the point then of creating a local or remote EJB with all that overhead only to deploy them over and over and over again inside each application? "I have one thing to say: RE-ENTR-ANT."

                      We have three databases that every one of our applications will utilize to some degree. The related EJB JARS should be deployed at the server level (remote or local, depends) - and I did exactly that. But of course, @EJB doesn't work. Ok, fine, I'll look them up - that works. But when the related domain classes are not deployed with the Seam EAR the concept of Seam's stateful entity bean breaks and the whole model ends up wasting effort and memory.

                      Its one thing to lookup an EJB and get a List back of domain beans inside Seam. But to seam...they are just a nameless POJOs and cannot be managed by the container (on a form submittal, e.g.).

                      We need a way in components.xml to "import" Seam beans from other sources, such as a globally deployed EJB JAR, into the Seam context so they can be AutoCreated when needed, etc. Something like:

                      core:import
                         jndi-pattern="" - for EJBs
                         seam-beans="" - for @Named POJOs in a jar

                      Each of those markups should support multiple entries.




                      • 8. Re: injection of existing ejb
                        Yaroslav Klymko Newbie

                        Unfortunately I have the same problem, could some one write down the detailed solution?


                        • 9. Re: injection of existing ejb
                          Arbi Sookazian Master

                          Stuart Douglas wrote on Feb 09, 2009 06:14:


                          @EJB is part of the EJB spec, not the seam spec. You can only use it inside other EJB's.


                          Incorrect.  See pg. 47 of EJB3 in Action for an example of @EJB usage in a Servlet...


                          So if this is allowed, then you should be able to use @EJB in a JavaBean Seam backing bean...


                          Is this problem restricted to remote interface injections or both remote and local injections of EJBs?

                          • 10. Re: injection of existing ejb
                            Stuart Douglas Master

                            You can only use it in places defined by the appropriate specification. Which does include servlets, but does not include seam components.





                            So if this is allowed, then you should be able to use @EJB in a JavaBean Seam backing bean...



                            I don't know how you decided that servlets and seam components are the same thing...

                            • 11. Re: injection of existing ejb
                              Arbi Sookazian Master

                              JSR220-core doesn't seem to lay down any rules regarding which types of components can or cannot use @EJB to inject.  It doesn't provide an example with a servlet.  There is usage of @EJB in session beans.


                              EJB3 in Action is more clear on this (see section 12.2.2):


                              Sometimes you’ll find that you need to access a session bean from a class that is not managed. Dependency injection is not supported in nonmanaged classes. For example, your JSF managed bean may be using some utility classes that are not managed by the container. You cannot inject an instance of an EJB into those classes. Again, in this case you must use JNDI lookup to access your session bean. This method is also used by managed classes when you want to avoid injection. For looking up an EJB from a helper class you have to do the following:


                                 1. Establish the reference to EJB by using the @EJB annotation at the class level or the ejb-ref (ejb-local-ref) descriptor element.
                                 2. Look up the session bean.


                              Remember from our discussion in part 2 of this book that the @EJB annotation can be used for injecting session bean references to a field or a setter method or can be applied at the class level to establish a reference that can be used with JNDI lookup.


                              The class where you use the @EJB annotation should be the managed class that uses a helper class. For example, say you have a helper class named BidProcessor that is used by ActionBazaarBidControllerServlet. The BidProcessor class looks up the PlaceBid EJB. You cannot use the @EJB annotation with the BidProcessor class because it is not a managed class. Here the entry point for the BidProcessor class is ActionBazaarBidControllerServlet, and that’s the reason we can use the @EJB annotation as follows:


                              @EJB (name = "ejb/PlaceBid", beanInterface = PlaceBid.class)
                              public class ActionBazaarBidControllerServlet extends HttpServlet {
                              }




                              Then look up the EJB in the helper class (BidProcessor) like this:


                              PlaceBid placeBid = (PlaceBid)context.lookup("java:comp/env/ejb/PlaceBid");
                              
                              placeBid.addBid(bidderId, itemId, bidPrice);

                              • 12. Re: injection of existing ejb
                                Arbi Sookazian Master

                                Jacques Lemire wrote on Jan 20, 2009 05:42:


                                I am working on an application where the ejb model that is not seam-enabled, but exposes services to a seem web application. In that context, we saw little sense to make the seam components ejbs, so we are deploying the web-app as a war, with the jsf backed by seam POJOs.


                                The current app I am working on has many session beans (mostly stateless and non-Seam components - i.e. no @Name on these SLSBs) that are injected using @EJB in SFSB backing beans.  All you need to do is to add @Stateful to your POJO, implement a local interface and add a @Remove method and then you can inject using @EJB.