1 2 Previous Next 16 Replies Latest reply on Nov 24, 2010 10:01 AM by alesj

    EJBTHREE-2198 EJB resource providers for switchboard and the dependency issues

    jaikiran

      Here's a quick overview of what the @EJB, ejb-ref, ejb-local-ref resource provider is expected to do. More details about what a ResourceProvider is and what role it plays can be found in this wiki http://community.jboss.org/wiki/Switchboard

       

      Goal:

       

      Consider this @EJB reference (in a servlet, for example):

       

      public class MyServlet
      {
      
          @EJB
          private MyBeanIntf bean;
          
      }
      
      

       

      And then consider this EJB:

       

      @Stateless
      public class MySLSB implements MyBeanIntf    
      {
      ...
          
      }    
      
      

       

      So ultimately, when the web application is being deployed, the servlet container shouldn't "start" unless the Resource (check the above wiki for what it means) corresponding to:

       

      @EJB
      private MyBeanIntf bean;
      
      

       

      is made available in the ENC (java:comp/env) of the servlet.

       

      EJB container implementation details:

       

      The JBoss EJB3 container in AS6 is a MC bean. When the JBoss EJB3 container finds a EJB (MySLSB in this case), among various other things, it binds the proxies to (JBoss specific) jndi names during its "start" (MC) lifecycle method. This has been legacy since AS5.

       

      Starting AS6 when we started supporting EJB3.1, we also bind the EJB proxies to a spec compliant JNDI name (along with the JBoss specific jndi names). The binding to EJB3.1 compliant JNDI names is done by the EJBBinder https://github.com/jbossejb3/jboss-ejb3-jndi/blob/master/binder/src/main/java/org/jboss/ejb3/jndi/binder/EJBBinder.java and has no interaction with the EJB containers. i.e. binding to EJB3.1 spec compliant jndi names is (intentionally) completely decoupled from EJB containers. The EJBBinder is deployed as a MC bean by the EJBBinderDeployer https://github.com/jbossejb3/jboss-ejb3-jndi/blob/master/deployers/src/main/java/org/jboss/ejb3/jndi/deployers/EJBBinderDeployer.java, so that the binding happens during the "start" lifecycle of that MC bean (when any necessary dependencies on the EJBBinder are satisfied)

       

      Currently in AS6, we bind the EJB3.1 jndi names as LinkRefs to jboss specific jndi names. So the EJBBinder creates and returns a LinkRef to the JBoss specific jndi name which will be created by the JBoss EJB3 containers.

       


      The ResourceProvider details and the problem:

       

      The ResourceProvider for @EJB, ejb-local-ref and ejb-ref is responsible for resolving the MC bean name of the EJBBinder from a ejb-ref, ejb-local-ref and @EJB. How the resolution is done is currently not relevant for this discussion. Let's just assume that we somehow manage to resolve it to a EJBBinder. The ResourceProvider then return this EJBBinder back to switchboard which converts this to a MC dependency. i.e. SwitchBoard adds a dependency on the servlet container for this EJBBinder MC bean to be installed before the servlet container can make available the servlet. Ideally, this should all work out, but there's a minor little detail in this implementation which causes it to fail. Let's see why:

       

      1) Web container (through SwitchBoard and RPs) adds a dependency on the EJBBinder responsible for setting up EJB3.1 spec compliant java:global jndi name of MySLSB
      2) EJBBinder is added as a MC bean
      3) EJBContainer corresponding to MyBean is added as a MC bean
      4) MC starts installing MC beans. Let's assume it picks up EJBBinder first. EJBBinder "starts" and binds to java:global a LinkRef
      5) MC sees that the EJBBinder dependency for web container is now satisfied and triggers the web container startup
      6) Web container starts initialzing instances (like load-on-startup servlets, filters etc...)
      7) While injecting from ENC to filter/servlet, container runs into error because the EJBContainer (#3) which is responsible for setting up the JBoss specific JNDI names, which are the target of the LinkRef created in #4, hasn't yet been triggered for "start" by MC.

       


      Solution:

       

      For AS6 we somehow need to add a dependency on the EJBBinder such that it isn't installed until the JBoss specific jndi names aren't bound into JNDI. It isn't easy because the code responsible for deploying EJBBinder as a MC bean (i.e. EJBBinderDeployer) somehow needs to know what the JBoss specific JNDI names are for each of the exposed view of the bean.

       

      Note that this may not be the only solution and there might be other ways to get past this. But the goal is to get this up and running as quickly as possible without having to change a lot of stuff.

        • 1. Re: EJBTHREE-2198 EJB resource providers for switchboard and the dependency issues
          wolfc

          That's solution part 1. It won't take care of circular references.

           

          Solution part 2 is to have EJBBinder bind lazy proxies which can connect to the EJBContainer on invocation (except for SFSB).

          • 2. Re: EJBTHREE-2198 EJB resource providers for switchboard and the dependency issues
            wolfc

            A complete alternative we're discussing on IRC is having EJBBinder bind a lazy ObjectFactory instead which does a lookup to the legacy JNDI name.

            • 3. Re: EJBTHREE-2198 EJB resource providers for switchboard and the dependency issues
              alesj
              For AS6 we somehow need to add a dependency on the EJBBinder such that it isn't installed until the JBoss specific jndi names aren't bound into JNDI. It isn't easy because the code responsible for deploying EJBBinder as a MC bean (i.e. EJBBinderDeployer) somehow needs to know what the JBoss specific JNDI names are for each of the exposed view of the bean.

              What are "JBoss specific jndi" names?

              Where / how do we get them?

              • 4. Re: EJBTHREE-2198 EJB resource providers for switchboard and the dependency issues
                alesj
                7) While injecting from ENC to filter/servlet, container runs into error because the EJBContainer (#3) which is responsible for setting up the JBoss specific JNDI names, which are the target of the LinkRef created in #4, hasn't yet been triggered for "start" by MC.

                Do we have a failing test(s) for this?

                e.g. in AS_testsuite

                • 5. Re: EJBTHREE-2198 EJB resource providers for switchboard and the dependency issues
                  jaikiran

                  Ales Justin wrote:

                   

                  7) While injecting from ENC to filter/servlet, container runs into error because the EJBContainer (#3) which is responsible for setting up the JBoss specific JNDI names, which are the target of the LinkRef created in #4, hasn't yet been triggered for "start" by MC.

                  Do we have a failing test(s) for this?

                  e.g. in AS_testsuite

                  No there aren't any tests specifically for this. This issue keeps occuring transiently when SwitchBoard and EJB3 containers is integrated into AS trunk, because in theory it all depends on which MC bean gets picked up first in step#4 by MC container for resolution.

                  • 6. Re: EJBTHREE-2198 EJB resource providers for switchboard and the dependency issues
                    alesj

                    Jaikiran listed the places where JBoss specific jndi bindings take place:

                    1) the legacy @SLSB and @SFSB is done in EJBContainer of jboss-ejb3-core (see the start)
                    2) for @Singleton container it in done in SingletonBeanJNDIBinderDeployer in jboss-ejb3-singleton project
                    3) for no-interface views it's done in EJB3NoInterfaceViewDeployer in jboss-ejb3-nointerface project
                    let me get you the git url for #2 and #3
                    #1 is in Ejb3/trunk in svn
                    #2 in https://github.com/jbossejb3/jboss-ejb3-singleton "deployer" module
                    #3 in https://github.com/jbossejb3/jboss-ejb3-nointerface "impl"
                    • 7. Re: EJBTHREE-2198 EJB resource providers for switchboard and the dependency issues
                      alesj

                      I would need a bit more info / explanation on how to get these custom jndi names for each diff type.

                      1) the legacy @SLSB and @SFSB is done in EJBContainer of jboss-ejb3-core (see the start)

                      How do I get a hold of this EJBContainer?

                      Afais, this is a MC bean under the JBossEnterpriseBeanMetaData::getContainerName?

                       

                      2) for @Singleton container it in done in SingletonBeanJNDIBinderDeployer in jboss-ejb3-singleton project
                      3) for no-interface views it's done in EJB3NoInterfaceViewDeployer in jboss-ejb3-nointerface project

                      OK, this two are obviously MC beans. :-)

                       

                      For all 3 "jndi" binders:

                      a) Which is the code that does the custom JBoss jndi binding?

                      b) Can it be already used from external bean/resource or does it need to be extracted / refactored?

                       

                      I can determine (b) myself, once I can identify the jndi binding code. ;-)

                      • 8. Re: EJBTHREE-2198 EJB resource providers for switchboard and the dependency issues
                        jaikiran

                        Ales Justin wrote:

                         


                        How do I get a hold of this EJBContainer?

                        Afais, this is a MC bean under the JBossEnterpriseBeanMetaData::getContainerName?

                        That's correct.

                         

                         

                        Ales Justin wrote:

                         

                        2) for @Singleton container it in done in SingletonBeanJNDIBinderDeployer in jboss-ejb3-singleton project
                        3) for no-interface views it's done in EJB3NoInterfaceViewDeployer in jboss-ejb3-nointerface project

                        OK, this two are obviously MC beans. :-)

                         

                        For all 3 "jndi" binders:

                        a) Which is the code that does the custom JBoss jndi binding?

                         

                         

                         

                        For no-interface jndi binding, it's the org.jboss.ejb3.nointerface.impl.jndi.NoInterfaceViewJNDIBinderFacade (MC bean) which does this binding.

                         

                        For singletons it's the org.jboss.ejb3.singleton.deployer.JNDIBinderImpl

                         

                        Ales Justin wrote:

                         


                        b) Can it be already used from external bean/resource or does it need to be extracted / refactored?

                         

                        I can determine (b) myself, once I can identify the jndi binding code. ;-)

                        It's not exposed yet and is internal impl details right now. Extracting/refactoring probably would require more work. I guess the easy way would be to use some specific MC bean name syntax for those binders and let the resource provider assume that syntax. For example:

                         

                        LegacyMCBeanNameSupplier (or whatever we call that):

                         

                        Set<String> getBinderDepencies(DeploymentUnit unit, JBossEnterpriseBeanMetaData metadata)
                        {
                            Set<String> dependencies = new HashSet<String>();
                            
                            // for singleton
                            if (metadata.isSession() && metadata.issingleton())
                            {
                                // add the binder, responsible for singleton view bindings, to the dependencies
                                // The MC bean name is assumed to be of the following syntax:
                                // jboss-ejb3-singleton-jndi-binder:appName=blah,module=blah,bean=beanName
                                dependencies.add("jboss-ejb3-singleton-jndi-binder:appName=myapp,module=myapp,bean=blahblah");
                            }    
                        
                            // for nointerface view
                            if (metadata.exposesNoInterfaceView)
                            {
                                // add the binder, responsible for no-interface view bindings, to the dependencies
                                // The MC bean name is assumed to be of the following syntax:
                                // jboss-ejb3-nointerface-jndi-binder:appName=blah,module=blah,bean=beanName
                                dependencies.add("jboss-ejb3-nointerface-jndi-binder:appName=myapp,module=myapp,bean=blahblah");
                            }
                            
                            // for SLSB and SFSB
                            if (metadata.isslsb || metadata.isSfsb)
                            {
                                // add legacy container MC bean as dependency
                                dependencies.add(metadata.getJBossMetadata().getContainerName());
                            }
                            
                            return dependencies;
                        }
                        
                        • 9. Re: EJBTHREE-2198 EJB resource providers for switchboard and the dependency issues
                          alesj
                              // for nointerface view     if (metadata.exposesNoInterfaceView)    

                          How do you know if there is no exposed interfaces?

                          Like this?

                           

                          if ((jsbmd.getBusinessLocals() == null || jsbmd.getBusinessLocals().size() == 0) &&
                                       (jsbmd.getBusinessRemotes() == null || jsbmd.getBusinessRemotes().size() == 0))

                          • 10. Re: EJBTHREE-2198 EJB resource providers for switchboard and the dependency issues
                            alesj
                                    // add legacy container MC bean as dependency         dependencies.add(metadata.getJBossMetadata().getContainerName());   

                            You mean metadata::getContainerName?

                            • 11. Re: EJBTHREE-2198 EJB resource providers for switchboard and the dependency issues
                              jaikiran

                              That was actually a pseudo code, so was probably a bit confusing. For identifying the presence of no-interface view:

                               

                              JBossEnterpriseBeanMetaData beanMetaData = ...
                              
                              if ( beanMetaData.isSession() && beanMetaData instanceof JBossSessionBean31MetaData)
                              {
                                  JBossSessionBean31MetaData sessionBeanMetaData = (JBossSessionBean31MetaData) beanMetaData;
                                  if(sessionBeanMetaData.isNoInterfaceBean())
                                  {
                                      // ....
                                  }
                              }
                              
                              • 12. Re: EJBTHREE-2198 EJB resource providers for switchboard and the dependency issues
                                alesj
                                        // add the binder, responsible for singleton view bindings, to the dependencies         // The MC bean name is assumed to be of the following syntax:         // jboss-ejb3-singleton-jndi-binder:appName=blah,module=blah,bean=beanName         dependencies.add("jboss-ejb3-singleton-jndi-binder:appName=myapp,module=myapp,bean=blahblah");    

                                I don't fully understand. :-)

                                 

                                Is this name sytax already used, and such beans are already installed?

                                If yes, there is a bit of inconsistency in the naming, EJBBinderDeployer uses application instead of appName.

                                If not, I don't see who would provide these beans into MC.

                                 

                                And what is supposed to be 'bean' in this case (instead of blahblah)?

                                • 13. Re: EJBTHREE-2198 EJB resource providers for switchboard and the dependency issues
                                  jaikiran

                                  Ales Justin wrote:


                                  Is this name sytax already used, and such beans are already installed?

                                  That syntax isn't being currently used and the MC beans being installed use some random internal naming scheme to deploy those MC beans.

                                   

                                  Ales Justin wrote:

                                  If yes, there is a bit of inconsistency in the naming, EJBBinderDeployer uses application instead of appName.

                                  If not, I don't see who would provide these beans into MC.

                                  We would require a change in the no-interface view and the singleton deployers. The reason I suggested that change was because to get the resource provider working, we do require some changes outside the resource provider and the simplest and quickly doable I could think of was that approach.

                                   

                                  Ales Justin wrote:

                                  And what is supposed to be 'bean' in this case (instead of blahblah)?

                                  Each EJB bean has a jndi binder (MC bean). the "bean" in such a case would be the name of the EJB. so the no-interface view and singleton binder deployer would install binders for each EJB using that naming scheme.

                                  • 14. Re: EJBTHREE-2198 EJB resource providers for switchboard and the dependency issues
                                    alesj

                                    OK, I think I now understand where this is going. :-)

                                    Who will then change the no-interface view and singleton binder / deployer to use this new naming schema?

                                    Should I do this or will you do it?

                                    (I'm still lost on 1M of your ejb3 subprojects )

                                    Each EJB bean has a jndi binder (MC bean). the "bean" in such a case would be the name of the EJB. so the no-interface view and singleton binder deployer would install binders for each EJB using that naming scheme.

                                    What's the EJB name in this case -- from JBossSessionBeanMetaData?

                                    JBossSessionBeanMetaData::getEjbName?

                                    1 2 Previous Next