1 2 Previous Next 17 Replies Latest reply on May 5, 2008 8:16 PM by Andrew Rubinger

    jndi name issues

    Scott Stark Master

      How does the following ejb-jar.xml/jboss.xml produce these bindings:

      <?xml version="1.0" encoding="UTF-8"?>
      <ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">
       <display-name>Ejb1</display-name>
       <enterprise-beans>
       <session>
       <ejb-name>TestBean</ejb-name>
       <home>com.sun.ts.tests.appclient.deploy.compat12_50.TestBeanHome</home>
       <remote>com.sun.ts.tests.appclient.deploy.compat12_50.TestBean</remote>
       <ejb-class>com.sun.ts.tests.appclient.deploy.compat12_50.TestBeanEJB</ejb-class>
       <session-type>Stateless</session-type>
       <transaction-type>Bean</transaction-type>
       <security-identity>
       <use-caller-identity/>
       </security-identity>
       </session>
       </enterprise-beans>
      </ejb-jar>
      


      <?xml version="1.0" encoding="UTF-8"?>
      
      <jboss xmlns="http://www.jboss.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee
       http://www.jboss.org/j2ee/schema/jboss_5_0.xsd" version="3.0">
       <unauthenticated-principal>guest</unauthenticated-principal>
       <enterprise-beans>
       <session>
       <ejb-name>TestBean</ejb-name>
       <jndi-name>appclient_deploy_compat12_50_TestBean</jndi-name>
       <call-by-value>true</call-by-value>
       </enterprise-beans>
      </jboss>
      
      


       +- TestBean (class: org.jnp.interfaces.NamingContext)
       | +- home (proxy: $Proxy292 implements interface com.sun.ts.tests.appclient.deploy.compat12_50.TestBeanHome)
       +- appclient_deploy_compat12_50_TestBean (proxy: $Proxy290 implements interface org.jboss.ejb3.proxy.JBossProxy)
      


      2008-04-28 18:22:14,699 DEBUG [org.jboss.ejb3.proxy.factory.ProxyFactoryHelper:1022] Obtaining JNDI name from policy org.jboss.ejb3.jndipolicy.impl.PackagingBasedJndiBindingPolicy
      2008-04-28 18:22:14,700 DEBUG [org.jboss.ejb3.proxy.factory.BaseSessionProxyFactory:187] Binding proxy for TestBean in JNDI at appclient_deploy_compat12_50_TestBean
      2008-04-28 18:22:14,701 DEBUG [org.jboss.ejb3.proxy.factory.ProxyFactoryHelper:1022] Obtaining JNDI name from policy org.jboss.ejb3.jndipolicy.impl.PackagingBasedJndiBindingPolicy
      2008-04-28 18:22:14,702 DEBUG [org.jboss.ejb3.proxy.factory.ProxyFactoryHelper:1022] Obtaining JNDI name from policy org.jboss.ejb3.jndipolicy.impl.PackagingBasedJndiBindingPolicy2008-04-28 18:22:14,705 DEBUG [org.jboss.ejb3.proxy.factory.ProxyFactoryHelper:1022] Obtaining JNDI name from policy org.jboss.ejb3.jndipolicy.impl.PackagingBasedJndiBindingPolicy
      2008-04-28 18:22:14,706 DEBUG [org.jboss.ejb3.proxy.factory.stateless.StatelessRemoteProxyFactory:83] Binding proxy for TestBean in JNDI at TestBean/home
      


      There has to be a way for a deployer to look at the metadata in the context of a given ejb ref and be able to determine the jndi name for the binding. Right now its impossible with the logic being done by the proxy factories.

      We have the DefaultJndiPolicy/EjbDeploymentSummary in metadata and the EjbDeploymentSummary includes the JBossEnterpriseBeanMetaData for the bean whose jndi name is being processed. We don't have the jndi policy to use generally available in the JBossMetaData. We could add it to a merged view that bridged the annotation information which is the current source of the policy default.

      We have to get to the point where unit tests in metadata demonstrate how to obtain the jndi name for an ejb reference for every usecase. Currently this is not possible.


        • 1. Re: jndi name issues
          Andrew Rubinger Master

          Yes, I've come across issues related to this while centralizing the proxy/proxy factory code within EJB3 Core.

          So what we need is a single authority to determine what the JNDI binding will be, taking into consideration the default JndiBindingPolicy, @RemoteBinding/@LocalBinding, and XML overrides.

          Sounds like this is something I should talk over with Alexey tomorrow; how to get all this into JBossMetaData and merged together correctly.

          S,
          ALR

          • 2. Re: jndi name issues
            Scott Stark Master

            Yes. For now I'm trying to get tests passing by adding logic to the MappedReferenceMetaDataResolverDeployer, but this is implementation detail logic.

            • 3. Re: jndi name issues
              Andrew Rubinger Master

              Great; I'm looking forward to getting this logic extracted out and more easily tested. This is a good excuse.

              S,
              ALR

              • 4. Re: jndi name issues
                Carlo de Wolf Master

                It should work as follows:

                By default beans are bound in JNDI in the form "[ejbName]", regardless which interfaces are defined on the bean.
                Depending on whether an EJB3 deployment is packaged within an EAR the JNDI name will be prepended by the short name of the EAR. So for foo.ear/bar.jar/MyBean it will become "foo/MyBean".
                The final JNDI name can be overriden with the use of @LocalBinding, @RemoteBinding or the equivalents from jboss.xml.

                Whenever a lookup is performed on the final JNDI name a proxy is returned implemented all home and business interfaces. (1)
                To get a specific interface proxy you should do a lookup on "[JNDI name]/[interface]", where "interface" can be any home or business interface. Or "interface" can be one of the following keywords: "home", "localHome", "local" or "remote" to specify the category.
                If there are more business interfaces defined in one category, the returned proxy will implement all those interfaces.

                (1) CAVEAT: In case of conflicting method signatures a call to that proxy might throw an UndeclaredThrowableException or behave differently than expected. The only solution is doing a finer grained lookup. (EJBTHREE-786 and EJBTHREE-1222)

                For backwards compatibility: http://www.jboss.org/jbossejb3/docs/tutorial/jndibinding/jndi.html

                • 5. Re: jndi name issues
                  Alexey Loubyansky Master

                   

                  "Carlo" wrote:
                  foo.ear/bar.jar/MyBean it will become "foo/MyBean"


                  If we are going to follow this format then I don't see how the full JNDI name can be resolved on the metadata level. Since there is no info about parent deployment units. So, it seems like the JNDI name resolution is going to be split into the prefix and suffix parts (the later being resolved in the metadata).

                  • 6. Re: jndi name issues
                    Scott Stark Master

                    Carlo's post seems to have lost information in the quoted strings.

                    There will have to be an org.jboss.metadata.ejb.jboss.jndipolicy.spi.EjbDeploymentSummary input into the jndi name process, so the metadata layer only has the JBossMetaData with the DefaultJndiBindingPolicy. What Carlo is describing is the ejb3 DefaultJndiBindingPolicy. The ejb2x DefaultJndiBindingPolicy will be different to conform to its legacy defaults.

                    The @LocalBinding, @RemoteBinding or the equivalents from jboss.xml have to be incorporated into the JBossMetaData and the DefaultJndiBindingPolicy impls honor those overrides.

                    What matters is that we can unit test the jndi names in the metadata layer and have this match the server environment behavior. So a deployer needing to know the jndi name for a bean would:

                    1. Create the EjbDeploymentSummary(DeploymentUnit, JBossEnterpriseBeanMetaData)
                    2. Obtain the DefaultJndiBindingPolicy from the JBossEnterpriseBeanMetaData.JBossMetaData + DeploymentUnit.classLoader
                    3. Based on the reference info, call the approriate DefaultJndiBindingPolicy.get*JndiName(unitSummary) method to obtain the jndi name that should be used in the reference lookup.

                    For 3 we need a utility class that properly looks at the reference type to determine if this is a home/local-home, remote or local, business interface lookup.

                    • 7. Re: jndi name issues
                      Andrew Rubinger Master

                       

                      "wolfc" wrote:
                      It should work as follows:

                      By default beans are bound in JNDI in the form "", regardless which interfaces are defined on the bean.
                      Depending on whether an EJB3 deployment is packaged within an EAR the JNDI name will be prepended by the short name of the EAR. So for foo.ear/bar.jar/MyBean it will become "foo/MyBean".


                      This should be handled by the JndiBindingPolicy, and the default in place is currently an implementation of the legacy.

                      If we change the format "earName/jarName/beanName" to "earName/beanName", we lose the guarantee that the binding will be unique. Why remove "jarName" from here?

                      Remember, JndiBindingPolicy is in place to handle cases we haven't considered or need further definition. EJBs deployed in webapps need to be unique per WAR, for instance.

                      "wolfc" wrote:
                      The final JNDI name can be overriden with the use of @LocalBinding, @RemoteBinding or the equivalents from jboss.xml.


                      Yes, but XML must override our annotations. So the hierarchy is:

                      JndiBindingPolicy > @RemoteBinding.jndiBinding/@LocalBinding.jndiBinding > jboss.xml


                      S,
                      ALR

                      • 8. Re: jndi name issues
                        Scott Stark Master

                        There should probably also be a derived transient properties/methods on the JBossEnterpriseBeanMetaData level that wraps the deployment summary and resource ref logic so that the JBossEnterpriseBeanMetaData can be used standalone:

                        @XmlTransient
                        public EjbDeploymentSummary getDeploymentSummary()
                        {
                        }
                        public void setDeploymentSummary(EjbDeploymentSummary summary)
                        {
                        }
                        @XmlTransient
                        public String getJndiNameForRefrence(AnnotatedEJBReferenceMetaData ref)
                        @XmlTransient
                        public String getJndiNameForRefrence(EJBLocalReferenceMetaData ref)
                        @XmlTransient
                        public String getJndiNameForRefrence(EJBReferenceMetaData ref)
                        



                        • 9. Re: jndi name issues
                          Andrew Rubinger Master

                          Related issue to link if we define any additional JIRAs for this:

                          http://jira.jboss.com/jira/browse/EJBTHREE-1101

                          S,
                          ALR

                          • 10. Re: jndi name issues
                            Carlo de Wolf Master

                            I've re-edited my post. It's forum weirdness, because the text was still there.

                            "alex.loubyansky@jboss.com" wrote:
                            "Carlo" wrote:
                            foo.ear/bar.jar/MyBean it will become "foo/MyBean"


                            If we are going to follow this format then I don't see how the full JNDI name can be resolved on the metadata level. Since there is no info about parent deployment units. So, it seems like the JNDI name resolution is going to be split into the prefix and suffix parts (the later being resolved in the metadata).

                            We must have a notion of parent deployment units at metadata level, because else we'll have a problem with the persistence unit deployer (EJB3 Persisitence 6.2.2 Persistence Unit Scope).
                            "scott.stark@jboss.org" wrote:
                            For 3 we need a utility class that properly looks at the reference type to determine if this is a home/local-home, remote or local, business interface lookup.

                            Not really, you can just lookup "[ejbName]/[interface]".
                            "ALRubinger" wrote:
                            If we change the format "earName/jarName/beanName" to "earName/beanName", we lose the guarantee that the binding will be unique. Why remove "jarName" from here?

                            Being inline with our own documentation. :-)
                            We could change both.

                            • 11. Re: jndi name issues
                              Scott Stark Master

                               

                              "wolfc" wrote:

                              We must have a notion of parent deployment units at metadata level, because else we'll have a problem with the persistence unit deployer (EJB3 Persisitence 6.2.2 Persistence Unit Scope).

                              We have that in the form of the EjbDeploymentSummary.

                              "wolfc" wrote:

                              "scott.stark@jboss.org" wrote:
                              For 3 we need a utility class that properly looks at the reference type to determine if this is a home/local-home, remote or local, business interface lookup.

                              Not really, you can just lookup "[ejbName]/[interface]".


                              Then your not considering overrides form other sources such as annotations or xml. A binding of the form "[ejbName]/[interface]" is not going to be unique within an ear let alone the server.

                              If your talking about a "[ejbName]/[interface]" key against the JBossEnterpriseBeanMetaData:
                              @XmlTransient
                              public String getJndiName(String ejbName, String iface)
                              


                              ok, that works.


                              • 12. Re: jndi name issues
                                Alexey Loubyansky Master

                                 

                                "Carlo" wrote:
                                We must have a notion of parent deployment units at metadata level


                                I assumed that the metadata api is a representation of the XML and not more than that. Everything else should be a layer on top. I still think it's a good idea to separate parsing/unmarshalling issues (and later maybe marshalling) from the "using it" logic. Having everything in the same place may complicate the api and maintenance.

                                I suggest we develop some wrapping api that gives the view we need but not add these changes to the classes that map to XML. The api may live in the metadata project as well,

                                • 13. Re: jndi name issues
                                  Carlo de Wolf Master

                                   

                                  "scott.stark@jboss.org" wrote:
                                  Then your not considering overrides form other sources such as annotations or xml. A binding of the form "[ejbName]/[interface]" is not going to be unique within an ear let alone the server.

                                  Again, this is legacy. If it needs changing, then so be it. I would like to be backwards compatible to 4.2 as long as it's possible.

                                  If the deployment is happening within the context of an EAR the lookup becomes: "[earName]/[ejbName]/[interface]".

                                  • 14. Re: jndi name issues
                                    Scott Stark Master

                                    What do you mean by lookup? You appear to be showing the form of the resolved jndi name. That's of no use to me.

                                    The usecase that needs to be solved is that I have a reference to an ejb and I need to know what the jndi name is.

                                    1 2 Previous Next