10 Replies Latest reply on Oct 24, 2008 2:08 AM by jaikiran pai

    Default JNDI naming scheme in EJB3.0 and possible conflicts

    jaikiran pai Master

      The current default jndi binding scheme http://www.jboss.org/community/docs/DOC-9569 doesn't take into account the module name of the EJB. For example, if i have an ear named MyApp.ear containing 2 jar files First.jar and Second.jar and both containing a bean implementation AppManagerBean:

      First.jar:

      package org.myapp.first.impl;
      
      @Stateless
      @Remote (org.myapp.first.AppManager.class)
      public class AppManagerBean implements org.myapp.first.AppManager {
      
      public String getVersion() {
       return "1.0";
       }
      
      
      }
      


      Second.jar

      package org.myapp.second.impl;
      
      
      @Stateless
      @Remote (org.myapp.second.AppManager.class)
      public class AppManagerBean implements org.myapp.second.AppManager {
      public String getVersion() {
       return "2.0";
       }
      
      }
      


      Then as per the default JNDI naming scheme both these beans will resolve to MyApp/AppManagerBean/remote. From what i see in the current version, only one bean (the first one) gets bound to the JNDI and the other bean does not get bound:

      +- MyApp (class: org.jnp.interfaces.NamingContext)
       | +- AppManagerBean (class: org.jnp.interfaces.NamingContext)
       | | +- remote (class: Proxy for: org.myapp.first.AppManager)
       | | +- remote-org.myapp.first.AppManager (class: Proxy for: org.myapp.first.AppManager)
      


      Shouldn't we be logging a WARN message in the logs letting the user know of this conflict?

      P.S: EJB3.1 spec seems to address this with the global jndi name scheme which results in a unique jndi name in these cases.


        • 1. Re: Default JNDI naming scheme in EJB3.0 and possible confli
          jaikiran pai Master

          Thinking more about this, the conflict can arise even when there are 2 beans with the same classname (but different package names) in the same jar.

          Ex:

          MyApp.ear/Single.jar

          package org.myapp.business;
          
          @Stateless
          public class ManagerBean implements org.myapp.business.Manager {
          
          }



          package org.myapp.persistence;
          
          @Stateless
          public class ManagerBean implements org.myapp.persistence.Manager {
          
          }




          • 2. Re: Default JNDI naming scheme in EJB3.0 and possible confli
            Carlo de Wolf Master

            The first example is a pain, which is easily circumvented by setting another JNDI policy. Which will be the cases when we go 3.1.

            The second example will even fail in 3.1, but I consider it bad practice to have two classes with the same name in 1 module.

            • 3. Re: Default JNDI naming scheme in EJB3.0 and possible confli
              Andrew Rubinger Master

              This is all just because we default the EJB Name in the case it's not specified.

              So the workaround is to set it explicitly.

              Otherwise we could default the EJB Name to the FQN of the bean impl class, but I think that'll cause more problems (migration) that it'll solve.

              S,
              ALR

              • 4. Re: Default JNDI naming scheme in EJB3.0 and possible confli
                jaikiran pai Master

                 

                "wolfc" wrote:

                The second example will even fail in 3.1, but I consider it bad practice to have two classes with the same name in 1 module.


                I think the second example will be handled gracefully in 3.1 as per the specs (Section 4.4.1):

                Each portable session bean global JNDI name has the following syntax :

                java:global[/<app-name>]/<module-name>/<bean-name>#<fully-qualified-interface-name>

                The container registers a separate global JNDI name entry for each local business interface, each remote business interface, and any no-interface view, 2.x local home interface, or 2.x remote home interface. For the the no-interface view, the last portion of the entry name is the fully-qualified bean class name.


                The fully-qualified-interface-name will generate a unique JNDI name.

                "ALRubinger" wrote:

                Otherwise we could default the EJB Name to the FQN of the bean impl class, but I think that'll cause more problems (migration) that it'll solve.


                I agree - changing the default EJB name at this point would not be of much help for this not so common scenario.

                "ALRubinger" wrote:

                So the workaround is to set it explicitly.


                Right, but the current behaviour just silently ignores the 2nd EJB and does not bind it. So if we have the information that we have already bound bean1 to the same name then maybe we could log a WARN message to highlight this issue so that the user opts for the workaround.





                • 5. Re: Default JNDI naming scheme in EJB3.0 and possible confli
                  jaikiran pai Master

                   

                  "jaikiran" wrote:

                  I think the second example will be handled gracefully in 3.1 as per the specs (Section 4.4.1):

                  Each portable session bean global JNDI name has the following syntax :

                  java:global[/<app-name>]/<module-name>/<bean-name>#<fully-qualified-interface-name>

                  The container registers a separate global JNDI name entry for each local business interface, each remote business interface, and any no-interface view, 2.x local home interface, or 2.x remote home interface. For the the no-interface view, the last portion of the entry name is the fully-qualified bean class name.


                  The fully-qualified-interface-name will generate a unique JNDI name.



                  On second thoughts, Carlo is right. The following scenario will not work even in 3.1:

                  Both packaged in same EAR/JAR:

                  package org.myapp.business;
                  
                  @Stateless
                  public class ManagerBean implements org.myapp.Manager {
                  
                  }
                  



                  package org.myapp.persistence;
                  
                  @Stateless
                  public class ManagerBean implements org.myapp.Manager {
                  
                  }
                  


                  Both of these will resolve to

                  java:global[/<app-name>]/<module-name>/ManagerBean#org.myapp.Manager
                  



                  • 6. Re: Default JNDI naming scheme in EJB3.0 and possible confli
                    Andrew Rubinger Master

                     

                    "jaikiran" wrote:
                    Right, but the current behaviour just silently ignores the 2nd EJB and does not bind it.


                    There's no exception thrown when binding to an already bound address?

                    "jaikiran" wrote:
                    So if we have the information that we have already bound bean1 to the same name then maybe we could log a WARN message to highlight this issue so that the user opts for the workaround.


                    Better to fail the whole deployment w/ a descriptive exception.

                    S,
                    ALR

                    • 7. Re: Default JNDI naming scheme in EJB3.0 and possible confli
                      jaikiran pai Master

                       

                      "ALRubinger" wrote:

                      There's no exception thrown when binding to an already bound address?


                      No exceptions in JBoss AS 4.2.3 GA. Fails with exception on deployment on JBoss-5 CR2.

                      Going by the logs looks like something to do with the org.jboss.ejb3.stateless.BaseStatelessProxyFactory which is doing with binding in 4.2.3 GA. Let me setup the 4.2.3 source code to dig more into this.

                      • 8. Re: Default JNDI naming scheme in EJB3.0 and possible confli
                        jaikiran pai Master

                         

                        "jaikiran" wrote:


                        No exceptions in JBoss AS 4.2.3 GA.

                        Going by the logs looks like something to do with the org.jboss.ejb3.stateless.BaseStatelessProxyFactory which is doing with binding in 4.2.3 GA. Let me setup the 4.2.3 source code to dig more into this.


                        Found this in org.jboss.ejb3.stateless.BaseStatelessProxyFactory

                        protected void bindProxy(Object proxy) throws NamingException
                         {
                         try
                         {
                         log.debug("Binding proxy for " + getContainer().getEjbName() + " in JNDI at " + jndiName);
                         Util.rebind(getContainer().getInitialContext(), jndiName, proxy);
                         } catch (NamingException e)
                         {
                         NamingException namingException = new NamingException("Could not bind stateless proxy with ejb name " + getContainer().getEjbName() + " into JNDI under jndiName: " + getContainer().getInitialContext().getNameInNamespace() + "/" + jndiName);
                         namingException.setRootCause(e);
                         throw namingException;
                         }
                         }


                        For some reason Util.rebind is being used instead of Util.bind. That explains why the exception is not thrown.

                        Do you think it was intentional to use rebind for some reason? If not, do you want me to create a JIRA to fix this?

                        • 9. Re: Default JNDI naming scheme in EJB3.0 and possible confli
                          Andrew Rubinger Master

                           

                          "jaikiran" wrote:
                          If not, do you want me to create a JIRA to fix this?


                          Well, Branch_4_2 is dead (meaning no more releases from there) so I wouldn't much see the point... :)

                          S,
                          ALR