7 Replies Latest reply on Jan 27, 2009 1:24 PM by bryan.kearney

    2 Stateless session beans, same name+interface, different ja

    gr28

      Hello,

      using JBoss 4.2.3

      We are having a Stateless Session bean with a specific name ("mybean"):

      @Local(IBean1.class)
      @Stateless(name="mybean")
      public class Bean1 implements IBean1 {

      The class Bean1 and the interface IBean1 belong to core.jar.

      An other SLSB (in core.jar) injects the "mybean" bean:

      @EJB(beanName="mybean")
      IBean1 beanImpl;

      I now want to replace the bean under name "mybean" with a project specific implementation. We add project.jar, which has a dependeny to core.jar. It deploys the following bean:

      @Local(IBean1.class)
      @Stateless(name="mybean")
      public class Bean1Project implements IBean1 {

      The "mybean" is now registered under JNDI as follows:

      ear=naming.ear,jar=core.jar,name=mybean,service=EJB3
      ear=naming.ear,jar=project.jar,name=mybean,service=EJB3

      After a simple test I found out that beanImpl gets an instance of Bean1Project injected. Can anyone please explain, why that bean is used?
      Is it possible to remove the SLSB from JNDI defined in core.jar without changing core.jar? The requirement is that the product core defines several SLSB that are always deployed and can always be replaced by a project specific implementation.

      Thank you for any help!

      Georg Raffer

        • 1. Re: 2 Stateless session beans, same name+interface, differen
          jaikiran

           

          "gr28" wrote:

          After a simple test I found out that beanImpl gets an instance of Bean1Project injected.


          Are you saying that when in a XYZBean (in core.jar), you are trying to inject "mybean", then the server is injecting mybean from the project.jar instead of core.jar?


          • 2. Re: 2 Stateless session beans, same name+interface, differen
            gr28

             

            Are you saying that when in a XYZBean (in core.jar), you are trying to inject "mybean", then the server is injecting mybean from the project.jar instead of core.jar?

            Yes. That is how it works in my test case. Is that a suprise for you? I would have expected that the bean from core.jar is used.

            bye, Georg

            • 3. Re: 2 Stateless session beans, same name+interface, differen
              jaikiran

              Georg,

              Can you please post the entire console logs and also the jndi tree contents. For viewing the jndi tree, please follow these steps http://wiki.jboss.org/wiki/DisplayTheJDNITreeWithTheJMXConsole

              While posting the logs or xml content or code, remember to wrap it in a code block using the Code button in the message editor window and please hit the Preview button to make sure your post is correctly formatted

              • 4. Re: 2 Stateless session beans, same name+interface, diff. ja
                gr28

                Hi,

                sorry for my very late response.

                Here is the JNDI tree:

                # ear=test.naming.ear,jar=test.naming.core.jar,name=b1,service=EJB3
                # ear=test.naming.ear,jar=test.naming.core.jar,name=wsTest,service=EJB3
                # ear=test.naming.ear,jar=test.naming.project.jar,name=b1,service=EJB3
                


                what we want is to replace an implementation (SLSB) by deploying it with the same name, but a different ejb module.

                wsTest SLSB uses b1 (dependency injection) which is located in the same ejb module in this example.

                we now want to replace the implementation by a project specific one (est.naming.project.jar). It implements the local interface and uses the same name (b1).

                What we want to achieve: We want that
                test.naming.core.jar,name=wsTest

                gets
                test.naming.project.jar,name=b1

                injected instead of
                test.naming.core.jar,name=b1

                by configuring it global. I found out (or assume) that JBoss injects the implementation that is loaded at the last. By changing the order of the modules in applcation.xml it either uses the implementation of core or project.

                Is that the exact definition how JBoss defines which implementation to use?
                Is it possible to influence the behavior by any JNDI hook?

                Thank you in advance!

                bye, Georg

                P.S: You can download the complete example code (eclipse projects) at:
                http://www.im-consultants.at/public/test.naming.zip[/url]

                • 5. Re: 2 Stateless session beans, same name+interface, differen
                  jaikiran

                  I do see the issue with the example that you have posted:

                  18:41:37,552 INFO [STDOUT] invoking: greenwich.naming.WsTestBean
                  18:41:37,552 INFO [STDOUT] class of IBean used: greenwich.naming.BeanImpl2
                  

                  I think the problem is because of the default jndi naming policy for EJBs. By default, the beans are bound to EARName/BeanName/local. Since in this case the BeanName (i.e. @Stateless(name="b1")) is the same for both the beans, the second bean (i.e BeanImpl2) is always injected by the EjbEncInjector.inject method . I have to look into the code to understand whether this is a bug. In the meantime, you have a workaround:

                  1) Add a @LocalBinding annotation to each of the beans to bind them to unique jndiNames as follows:
                  package greenwich.naming;
                  
                  import javax.ejb.Stateless;
                  
                  import org.jboss.annotation.ejb.LocalBinding;
                  
                  @Stateless(name="b1")
                  @LocalBinding(jndiBinding = "Core-b1")
                  public class BeanImpl1 implements IBean {
                   public void invoke(){
                   System.out.println("class of IBean used: " + getClass().getName());
                   }
                  }
                  


                  BeanImpl2:

                  package greenwich.naming;
                  
                  import javax.ejb.Stateless;
                  
                  import org.jboss.annotation.ejb.LocalBinding;
                  
                  @Stateless(name="b1")
                  @LocalBinding(jndiBinding = "Project-b1")
                  public class BeanImpl2 implements IBean {
                   public void invoke(){
                   System.out.println("class of IBean used: " + getClass().getName());
                   }
                  }
                  


                  You don't have to change anything else not even the injection part:

                  @Stateless(name="wsTest")
                  @WebService(name="naming")
                  public class WsTestBean implements IWsTestBean {
                   @EJB(beanName="b1")
                   IBean beanImpl;
                  
                   @WebMethod
                   public void testNaming(){
                   System.out.println("invoking: " + getClass().getName());
                   beanImpl.invoke();
                   }
                  }
                  


                  This should get it working properly, as i saw on my local setup (after the workaround):
                  18:43:05,868 INFO [STDOUT] invoking: greenwich.naming.WsTestBean
                  18:43:05,868 INFO [STDOUT] class of IBean used: greenwich.naming.BeanImpl1



                  • 6. Re: 2 Stateless session beans, same name+interface, differen
                    gr28

                    Hi,

                    Thank you for your response.
                    The usage of @LocalBinding seems to help. But anyway, is it possible to intercept the decision process (the JNDI injection) in JBoss?

                    Our use case is simple:
                    We have a product that implements default behavior. For projects a specific implementation should be used by the product, without changing the product code!

                    So if we use a code of

                    @EJB(beanName="b1")
                     IBean beanImpl;
                    


                    and we have 2 implementations named b1 (one in the product and one project specific), we want to decide (globally by configuration) which implementation to use.

                    bye, Georg

                    --
                    www.im-consultants.at


                    • 7. Re: 2 Stateless session beans, same name+interface, differen
                      bryan.kearney

                      Did you ever get an answer to this? Did you have to go to using JNDI directly.. or some other solution?