1 2 Previous Next 19 Replies Latest reply on Mar 27, 2014 7:04 AM by Eduardo Martins

    Portable Naming and Binding of Resources

    Thomas Kriechbaum Newbie

      Hello,

       

      how do I have to define resources (DataSource, URL) in a portable way, so that an EAR can be deployed without any changes to different server configurations (e.g. Test/Production; Customer A/Customer B)?

      Is portability of JNDI names an open issue in general?

       

      E.g. arungupta noted in Migrating a Java EE App from GlassFish to WildFly · WildFly)

      "Because of differences in the JNDI naming rules, it’s necessary to change all occurrences of the previous JNDI name to the new one. "


      To be more specific:

      We typically package service applications as EARs containing one WAR- and one or more EJB-Modules (EJB-JARs are packaged within WEB-INF/lib as part of the WAR). All these modules should have access to the same configuration URL or DataSource using the app-namespace (e.g. java:app/url/Configuration, java:app/jdbc/SandboxDS).The configuration URL and/or the DataSource can vary between different operating zones and/or customer deployments.

       

      As recommended in the Wildfly documentation (JNDI Reference - WildFly 8 - Project Documentation Editor) I tried to define a binding in the "Naming Subsystem Configuration" (standalone.xml). Since the resource should be accessible within the app-namespace I have specified the app-name as part of the global JNDI-name.

       

      <subsystem xmlns="urn:jboss:domain:naming:2.0">

          <bindings>

              <simple name="java:global/wildfly-services-ear-1.0.0/url/Configuration" value="file:///data/conf/test/wildfly-services-1.0.0" type="java.net.URL"/>

          </bindings>

          <remote-naming/>

      </subsystem>

       

      In my EJB, the correct app-name is provided by

      Context ctx = new InitialContext();

      String name = (String) ctx.lookup("java:app/AppName");

      ==> wildfly-services-ear-1.0.0

       

      ctx.lookup("java:global/wildfly-services-ear-1.0.0/url/Configuration")

      returns the expected URL, but

      ctx.lookup("java:app/url/Configuration")

      causes an NameNotFoundException.

       

      Because of this exception I tried to define the resource within the web.xml and bound it via jboss-web.xml. But binding URL-references does not work with Wildfly, because

      org.jboss.as.ee.utils.InjectionUtils.getInjectionSource(InjectionUtils.java:128)

      does not resolve JNDI-Names for java.net.URL types. In this case, the target URL has to be defined within jboss-web.xml directly.  But as mentioned above, the EAR itself must not be adopted for specific operating zones or customers.

      Is this way of URL resolving a known issue or the expected behavior?

       

      Whats about referencing  DataSources within the persistence.xml in a portable way (define and bind them external to the EAR)?

      e.g  <jta-data-source>java:app/jdbc/SandboxDS</jta-data-source>

       

      Thanks,

      Thomas

        • 1. Re: Portable Naming and Binding of Resources
          Eduardo Martins Apprentice

          No need to use the naming subsystem configuration for this, you may define URL and Datasources resources in the java:global and java:app portable namespaces through the EAR's application.xml or any EE component XML standard descriptor:

           

          <!-- binds a URL (factory) -->

          <resource-ref>

              <res-ref-name>java:app/url/Configuration</res-ref-name>

              <res-type>java.net.URL</res-type>

               <!-- the URL value is defined through lookup-name -->

              <lookup-name>file:///data/conf/test/wildfly-services-1.0.0</lookup-name>

          </resource-ref>

           

          <!-- bind of a datasource definition --

          <data-source>

               <name>java:app/jdbc/SandboxDS</name>

               <class-name>com.example.MyDataSource</class-name>

               <!-- ... -->

          </data-source>

           

          <!-- rebind of a datasource in another, possibly non portable, jndi name -->

          <resource-ref>

               <res-ref-name>java:app/jdbc/SandboxDS</res-ref-name>

               <res-type>javax.sql.DataSource</res-type>

               <lookup-name>java:jboss/ds/MyDS</lookup-name>

          </resource-ref>


          Use java:app to make these binds available only to components inside the EAR, use java:global to make these available to all deployments.

          • 2. Re: Portable Naming and Binding of Resources
            Thomas Kriechbaum Newbie

            Hello Eduardo,

             

            thanks for your reply.

             

            The point is that these deployment descriptors are part of the EAR and in my case the EAR must be the same for different deployments (system admins check md5 hash). At the moment then configuration URL is not the same for different deployments of one EAR. Maybe we have to think about this policy.

             

            Is java:jboss/ds/MyDS portable concerning different applications servers (Wildfly,Glassfish, WAS)? Or are deployment descriptor the perfect place to deal with container specific naming rules?


            I have to discuss this issue with our admins. Possibly, adopting the deployment descriptors during the deployment process is an option (e.g, the IBM WAS adds some product specific information to the EAR behind the scene as well).


            Thomas

            • 3. Re: Portable Naming and Binding of Resources
              Eduardo Martins Apprentice

              I'm not understanding what you mean with "EAR must be the same for different deployments (system admins check md5 hash)", care to explain? The advantage of using resource-ref in standard XML descriptors is that it will work out of the box for any Java EE compliant platform, no need to rely on proprietary configuration functionality such as the naming subsystem.

               

              PS: java:jboss is not portable, it exists only in WildFly. The portable namespaces are java:comp, java:module, java:app and java:global. Each has a different scope, I recommend you to check the section about resources/jndi in the Java EE 7 spec for the complete picture.

              • 4. Re: Portable Naming and Binding of Resources
                Stephen Coy Master

                Hi Thomas,

                 

                I have some experience building JavaEE applications that must run on multiple platforms. The use of proprietary deployment descriptors (such as jboss-app.xml, weblogic-application.xml or ibm-application-bnd.xml, as well as the ejb module and web module derivatives) when multi-platform deployment is necessary is mandatory.

                 

                These are used to map portable lookup names (such as java:comp/env/jdbc/myDS to java:jboss/ds/MyDS) to the resource name defined for each particular server vendor. The use of <lookup-name> elements is platform dependent.

                • 5. Re: Re: Portable Naming and Binding of Resources
                  Thomas Kriechbaum Newbie

                  Hi Eduardo,

                   

                  "EAR must be the same" means that an EAR provided by the development team (e.g. via build server) must not be changed by the admin team, even if the EAR should be deployed at different operating zones. Therefore, in our WAS infrastructure we define all specific resources in the application server's namespace and bind them during deployment. As even the WAS changes the EAR during deployment behind the scene, its ok to change the lookup-entries in the deployment descriptors. Thanks for your clarification.

                   

                  As you described, an URL resource can be directly defined in resource-ref/lookup-name within a deployment descriptor. Am I right, that this would have the same effect as

                   

                  @Resource(lookup="file:///data/conf/test/wildfly-services-1.0.0")

                  private URL configuration

                   

                  But it seems, that for URL references it is not possible to bind a app-name to a server-specific name within standalone.xml.

                  e.g.

                  <resource-ref>

                      <res-ref-name>java:app/url/Configuration</res-ref-name>

                      <res-type>java.net.URL</res-type>

                      <lookup-name>java:jboss/wildfly-services-1.0/url/Configuration</lookup-name>

                  </resource-ref>

                   

                  and

                   

                  <subsystem xmlns="urn:jboss:domain:naming:2.0">

                        <bindings>

                           <simple name="java:jboss/wildfly-services-1.0/url/Configuration" value="file:///data/config/wildfly-services-1.0" type="java.net.URL"/>

                       </bindings>

                       <remote-naming/>

                  </subsystem>

                   

                  The idea behind is, that the system admins should have a single configuration file to manage resource definitions. I looked at the implementation sources a while and it seems that resource targets of type URL are handled slightly different compared to other ones. Is <lookup-name>...</lookup-name> or @Resource(lookup="...") required to be a valid URL - java:jboss/.. or java:app/... is not excepted and causes an exception.

                   

                  Sorry for my questions, but I need this information to check how to deploy our service applications on several application servers.

                   

                  Thanks,

                  Thomas

                  • 6. Re: Portable Naming and Binding of Resources
                    Eduardo Martins Apprentice

                    Right, resource-ref's lookup-name and @resource's lookup have this particular different meaning of defining the URL value, so if you want to stay away from touching the EAR then perhaps binding the url as string in the naming subsystem configuration is the best option:

                     

                    <subsystem xmlns="urn:jboss:domain:naming:2.0">

                          <bindings>

                             <simple name="java:global/url/Configuration" value="file:///data/config/wildfly-services-1.0" type="java.lang.String"/>

                         </bindings>

                    </subsystem>


                    and then

                     

                    @Resource(lookup="java:global/url/Configuration")

                    private String configuration;


                    But if admins are able to put additional descriptors inside the EARs then you could follow the Stephen's route, which is what is commonly used in Java EE TCKs, and for WildFly add a jboss-app.xml with

                     

                    <resource-ref>

                        <res-ref-name>java:app/url/Configuration</res-ref-name>

                        <res-type>java.net.URL</res-type>

                        <lookup-name>file:///data/conf/test/wildfly-services-1.0.0</lookup-name>

                    </resource-ref>

                     

                    and then

                     

                    @Resource(lookup="java:app/url/Configuration")

                    private URL configuration;

                    • 7. Re: Re: Portable Naming and Binding of Resources
                      Stephen Coy Master

                      Hi Eduardo,

                       

                      I don't understand the idea of populating the resource value into the <lookup-name> element. Everything I've read has suggested that this should be a JNDI name.

                       

                      Typically, I've used JNDI to access environment dependent resources that have been configured in the server instance,as in the first part of your example above. Although I would expect to be able to declare:

                      <subsystem xmlns="urn:jboss:domain:naming:2.0">
                            <bindings>
                               <simple name="java:jboss/url/Configuration" value="file:///data/config/wildfly-services-1.0" type="java.net.URL"/>
                           </bindings>
                      </subsystem>
                      

                       

                      For cross-platform portability I would then have in my jboss-app.xml:

                      <resource-ref>
                          <res-ref-name>java:app/url/Configuration</res-ref-name>
                          <res-type>java.net.URL</res-type>
                          <lookup-name>java:jboss/url/Configuration</lookup-name>
                      </resource-ref>
                      

                      Note the type. And then:

                      @Resource(lookup="java:app/url/Configuration")
                      private URL configuration;
                      

                       

                      Additionally, with the new JavaEE namespaces I would expect to be able to simplify all of this to the following:

                      <subsystem xmlns="urn:jboss:domain:naming:2.0">
                            <bindings>
                               <simple name="java:global/url/Configuration" value="file:///data/config/wildfly-services-1.0" type="java.net.URL"/>
                           </bindings>
                      </subsystem>
                      

                      and

                      @Resource(lookup="java:global/url/Configuration")
                      private URL configuration;
                      

                      because all JavaEE 7 vendors should support binding entries into the "java:global/..." namespace - in the server instance configuration.

                      1 of 1 people found this helpful
                      • 8. Re: Re: Portable Naming and Binding of Resources
                        Eduardo Martins Apprentice

                        I don't recall exactly if it was the spec or schemas that referred this special behaviour, but [WFLY-2417] Support URL Connection Factory Resource Injection - JBoss Issue Tracker introduced it for WildFly, since there was a bunch of JEE 7 TCK tests requiring it.

                        • 9. Re: Portable Naming and Binding of Resources
                          Stephen Coy Master

                          Well, hardwiring URL's like that is almost useless. Most of the time the actual URL value will be different for each environment.

                           

                          Does that mean it's not possible to reference java.net.URL values that have been bound into the server's JNDI tree?

                           

                          This  is certainly something that I've done in the past on JBossAS (even 7.x), WebLogic and WebSphere.

                          • 10. Re: Portable Naming and Binding of Resources
                            Eduardo Martins Apprentice

                            Thinking about it, perhaps WildFly should support both cases, that is, if "lookup" is a URL then consider its value as mandated by the TCK, if not consider its the standard reference name to another JNDI entry. What do you think?

                            • 11. Re: Portable Naming and Binding of Resources
                              Eduardo Martins Apprentice

                              Stephen Coy wrote:

                               

                              Well, hardwiring URL's like that is almost useless. Most of the time the actual URL value will be different for each environment.

                               

                               

                              By the way, that was my thoughts about it first, and everyone else in #wildfly-dev when we discussed it, but I think the idea behind this is that there may be some advantage in managing the URL creation and usage, thus the name "URL Connection Factory" and its inclusion in the "Resource Manager Connection Factory" section of the spec, instead of adding java.net.URL type to the env entries type set.

                              • 12. Re: Portable Naming and Binding of Resources
                                Thomas Kriechbaum Newbie

                                Hi Eduardo,

                                 

                                the scenario decribed by Stephen would definitely help to implementiert portable JavaEE applications. At the moment  @Resource(lookup="java:...")

                                causes an exception.

                                 

                                Managing URL resources in standalone.xml would be perfect. In this case we only habe  to add container specific deplyment descriptors once and can define the environment specific URL within the server configuration.

                                 

                                 

                                Thomas

                                • 13. Re: Re: Portable Naming and Binding of Resources
                                  David Lloyd Master

                                  If this is the case, please file a JIRA issue and mark the priority as "Blocker" "Critical", and make sure it is assigned to Eduardo.  Edit: it does not need to be Blocker as this is a relatively edge case.

                                  • 14. Re: Portable Naming and Binding of Resources
                                    Stephen Coy Master

                                    Eduardo Martins wrote:

                                     

                                    Thinking about it, perhaps WildFly should support both cases, that is, if "lookup" is a URL then consider its value as mandated by the TCK, if not consider its the standard reference name to another JNDI entry. What do you think?

                                    That works for me. Especially considering that this works fine in AS7.x.

                                     

                                    As far as I can tell, that TCK behaviour is not defined in any specification and (given it's relative uselessness) I consider it to be a bug in the TCK.

                                    1 2 Previous Next