13 Replies Latest reply on Sep 30, 2008 8:34 AM by nimo stephan

    Using @In or @EJB

    nimo stephan Master

      In an EJB-Project, what should I prefer to inject SessionBeans?


      @In
      BeanInterface i;




      or



      @EJB
      BeanInterface i;



      What s the real difference?


      I found out, that when I tried it with @In then all works, but when I tried it with @EJB, then I get this error:



      18:31:52,843 ERROR [viewhandler] Error Rendering View[/view.xhtml]
      java.lang.NullPointerException
              at MyBean.getList(MyBean.java:81)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
              at java.lang.reflect.Method.invoke(Unknown Source)
              at org.jboss.seam.util.Reflections.invoke(Reflections.java:21)
              at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31)
              at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
              at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:46)
              at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
              at org.jboss.seam.persistence.ManagedEntityIdentityInterceptor.aroundInvoke(ManagedEntityIdentityInterceptor.java:43)
              at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
              at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:31)
              at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
              at org.jboss.seam.core.ConversationInterceptor.aroundInvoke(ConversationInterceptor.java:65)
              at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
              at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:42)
              at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)



      MyBean.getList retrieves a list coming from my EJB-injected SessionBean:



      MyBean {
      
      @EJB
      SessionBeanEJBLocal sessionBean;
      
      public List <Shift> getShiftList() {
      
      return sessionBean.getList();
      
      }




      When I do this, then all works:


      MyBean {
      
      @In
      SessionBeanEJBLocal sessionBean;
      
      public List <Shift> getShiftList() {
      
      return sessionBean.getList();
      
      }




      But why??


        • 1. Re: Using @In or @EJB
          Ivan Pazmino Newbie

          Hi,


          I believe it's because the annotation javax.ejb.EJB is from the EJB specification and has nothing to do with Seams's bijection features.


          In the other hand org.jboss.seam.annotations.In is the Seam's annotation to tell the context to inject the annotated component.


          Bijection in the manual (Item 4.3): http://docs.jboss.com/seam/latest/reference/en-US/html/concepts.html


          regards,

          • 2. Re: Using @In or @EJB
            nimo stephan Master

            I know that the @EJB has is not Seams's bijection..but normally it should be possible to inject a Interface in SEAM also via @EJB?!


            I dont know.

            • 3. Re: Using @In or @EJB
              Stuart Douglas Master

              Is mybean an EJB? If not it won't work

              • 4. Re: Using @In or @EJB
                nimo stephan Master

                upps..yeahh you are right!


                mybean is not an ejb..it s a pojo:-)



                EJBs can only communicate to each other?!..Using methods coming from an EJB, @In works fine.


                thanks.

                • 5. Re: Using @In or @EJB
                  Stuart Douglas Master

                  EJB annotations only work in EJB's, if you are using POJO's then you need to use seam's annotations instead. Seam provides an alternative to most of the EJB annotation.

                  • 6. Re: Using @In or @EJB
                    nimo stephan Master

                    The only thing, I do not understand well, is:


                    How can the view-logic invoke or access an EJB-Bean without using @In.


                    Is that not so, that the view-logic lying in the servlet-container asks for the business-methods coming from the ejb-container?


                    How can I force that (MVC) without using @In?

                    • 7. Re: Using @In or @EJB
                      Guillaume Jeudy Master

                      The view-logic (I guess you are referring to .xhtml pages here) has access to whatever is resolvable through EL-Unified expression. Seam will make available all Seam components through EL expressions.


                      Therefore you cannot resolve a plain EJB in your view layer. This only becomes possible when you make your EJB also a Seam component.


                      Your last question is not clear.


                      Can you tell us why you are trying to use @EJB instead of @In ?

                      • 8. Re: Using @In or @EJB
                        nimo stephan Master

                        Yes, I have a .xhtml representing the view-logic.


                        However, I have also a kind of managedBean (I call it viewBeans) representing the view-logic.


                        I know, in Seam there are no need of managedBeans
                        and I do not configure these viewBeans in faces-config !


                        I have these kinds of viewBeans to provide only view-related logic, such as eventlisteners, UI-Components, Servlet-Attributes and so on.


                        These ViewBeans are POJOs stored in the WAR!


                        In my ViewBeans, I use SEAM-Annotations such as @Session, @Conversation, @In, but I use no EJB-Annotations such as @Stateful, Stateless and the like.


                        This makes sense as these viewBeans should only exist in the servletContainer - With this approach I seperate the viewLogic from the businessLogic (MVC) !


                        The businessLogic are my SessionBeans and EntityBeans which only exists in the EJB-Container. In my SessionBeans, I do not use any view-related logic such as @Session, @Conversation and the like.


                        Now, the big question:


                        I have the pure business-methods lying in the EJB-Container and can provide these methods to my view-logic (POJO) via their session-interfaces only and (really only?) by @In.


                        Am I right?


                        I do not want to mix up view-code ans business-code. Do you use both view-logic and business-logic in your sessionBeans? You cannot develop your view only with tags. Sometimes, you need actionListeners or the kind and it is bad practice to put such code in your sessionBean!


                        What do you think?




                        • 9. Re: Using @In or @EJB
                          Guillaume Jeudy Master

                          Ah now thats clearer, You need to use @In only in your web layer POJOs.


                          You are right sometimes you need custom POJOs to handle view related logic and they should be in your web layer not the ejb module.


                          My session beans strive to have business-logic only in them.


                          You can go a pretty long way in developing the view with tags only. Facelets is pretty powerful with templating and allows you to build custom components through composition tags.


                          Check out this article: Facelets fits JSF like a glove

                          • 10. Re: Using @In or @EJB
                            Stuart Douglas Master
                            If you really don't want your buisness layer beans to be seam components you have two real options:

                            1) Look them up in JNDI. This is not the way to go

                            2) Create a seperate ejb jar just for view logic. This way your view backing beans can be ejb's as well and you can access the buisiness logic using @EJB. If you want to use @PerisitenceContext in both EJB Jars you will also have to split all your entitys and persistence.xml into a third (non ejb) jar (you will then have to reference it using @PersistenceContext(unitName="../myentitys.jar#myUnitName") if you are using jboss 4).
                            • 11. Re: Using @In or @EJB
                              nimo stephan Master

                              I want that my buisness layer to be seam components. However, I only want to seperate the view from the business logic.


                              I do something like so:


                              This is in my war:


                              @Name("managedBean")
                              @Scope(CONVERSATION)
                              public class ViewBean  {
                              
                              @In
                              myEJBLocal ejbLocal;
                              
                              ...
                              
                              }




                              This is my EJB:



                              @Name(myEjbBean)
                              @Stateless
                              @Scope(CONVERSATION)
                              public class myEJBBean implements MyEJBLocal {
                              
                              ..
                              }




                              I avoid mixing it like the following:


                              @Name(myEjbBean)
                              @Stateless
                              public class myEJBBean implements MyEJBLocal {
                              
                              ..
                              }



                              What s the purpose of mixing Scope-Types with SessionBeans ?
                              Scope-Types are for my Servlet-Container and not for my EJB-Container. So I provide all the Scope-Types to a viewBean without the need of an interface. Thats good, or?


                              So I can separate the view from the business logic and can access the business-methods via Seams injection. This makes sense. Don t you think?

                              • 12. Re: Using @In or @EJB
                                Stuart Douglas Master


                                @Stateless


                                @Scope(CONVERSATION)


                                This is defiantly wrong. I am not sure what you are tying to achieve here but you should never bind Stateless session beans to any scope other than stateless, which they are bound to by default.


                                • 13. Re: Using @In or @EJB
                                  nimo stephan Master

                                  Oh sorry, you are right. I meant:



                                  @Statefull
                                  @Scope(CONVERSATION) 



                                  However, with this annotation I mix up view-logic with ejb-logic, as the Scopes are only relevant to my Servlet-Container and the Statefull/Stateless to my EJB-Container.