1 Reply Latest reply on Sep 29, 2004 2:49 PM by alexm

    How to ensure proper binding of a data source

    alexm

      Hi,

      I am using JBoss 3.2.5 on Fedora Linux. I've followed steps in the latest O'Reilly book Enterprise JavaBeans and in JBoss manual for configuring data sources, but have received varying results. For example, by following the steps in the O'Reilly book my JBoss bound the data source to the default HyperSonic (?) database. I've figured so much that the problem is in how the data source is named and referenced, but I am still puzzled as to what the right way is to name and reference a JDBC data source.

      I've identified four places of interest (given on the example of MySQL DB):

      1. mysql-ds.xml
      2. jbosscmp-jdbc.xml
      3. ejb-jar.xml
      4. lookup code in Java


      mysql-ds.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <datasources>
       <local-tx-datasource>
       <jndi-name>SomeDB</jndi-name>
       <connection-url>jdbc:mysql://host:port/dbname</connection-url>
       <driver-class>com.mysql.jdbc.Driver</driver-class>
       <user-name>bla</user-name>
       <password>bla</password>
       </local-tx-datasource>
      </datasources>


      jbosscmp-jdbc.xml
      <?xml version="1.0" encoding="UTF-8"?>
      <jbosscmp-jdbc>
       <defaults>
       <datasource>java:/SomeDB</datasource>
       <datasource-mapping>mySQL</datasource-mapping>
       </defaults>
      </jbosscmp-jdbc>


      In ejb-jar.xml

      ...
      <resource-ref>
       <res-ref-name>jdbc/SomeDB</res-ref-name>
       <res-type>javax.sql.DataSource</res-type>
       <res-auth>Container</res-auth>
      </resource-ref>
      ...


      In the Java code:
      ...
      Context ictx = new InitialContext();
      DataSource someDS = (DataSource) ictx.lookup("jdbc/SomeDB");
      ...


      These files were placed in the right locations.

      The above combination doesn't work well. Using the JNDI name jdbc/SomeDB in mysql-ds.xml and java:/jdbc/SomeDB jbosscmp-jdbc.xml gives the same lookup problems. Instead of trying out all the possible combinations in the universe, can't someone simply explain what the right way to do this is and why that is so?

      For example, how does JBoss bind the resource reference name such as jdbc/SomeDB? Based on the name of this field, jdbc/SomeDB is just the name of the reference, but not necessarily the name of the resource, so how does the binding occur? I've read that jdbc prefix should be used for JDBC data sources, but where should it be used, in some of the locations above or all of them? And what about the prefixes java:, java:/comp/env/jdbc, etc. I've found conflicting information on the net.

      I should mention that I did get the whole thing to work but in the way different than explained in the book. The trick was to use java:/someDB in the Java lookup. What I didn't understand is what the role of the resource reference field was when I was referencing the resource directly based on its JNDI name and not based on the resource reference name?

      I admit that I may have some holes in my understanding of this topic, hence this post :).

      Thanks,
      Alex

        • 1. Re: How to ensure proper binding of a data source
          alexm

          Hi All,

          I've figured it out. What I failed to see is that jboss.xml should bind the resource reference name to the actual JNDI name of the resource.

          To summarize, here is a combination that works well:

          mysql-ds.xml

          <?xml version="1.0" encoding="UTF-8"?>
          <datasources>
           <local-tx-datasource>
           <jndi-name>jdbc/myApp/myDB</jndi-name>
           <connection-url>jdbc:mysql://host:port/dbname</connection-url>
           <driver-class>com.mysql.jdbc.Driver</driver-class>
           <user-name>bla</user-name>
           <password>bla</password>
           </local-tx-datasource>
          </datasources>


          jbosscmp-jdbc.xml

          <?xml version="1.0" encoding="UTF-8"?>
          <jbosscmp-jdbc>
           <defaults>
           <datasource>java:/jdbc/myApp/myDB</datasource>
           <datasource-mapping>mySQL</datasource-mapping>
           </defaults>
          </jbosscmp-jdbc>


          In ejb-jar.xml

          ...
           <resource-ref >
           <res-ref-name>jdbc/myDB</res-ref-name>
           <res-type>javax.sql.DataSource</res-type>
           <res-auth>Container</res-auth>
           </resource-ref>
           ...


          The following snippet (in jboss.xml) needs to be placed in the descriptor of EJBs that look up the data source in question:

          ...
           <resource-ref>
           <res-ref-name>jdbc/myDB</res-ref-name>
           <jndi-name>java:/jdbc/myApp/myDB</jndi-name>
           </resource-ref>
           ...


          In Java code, the lookup is performed as follows:

          ...
           Context ictx = new InitialContext();
           DataSource myDS = (DataSource) ictx.lookup("java:comp/env/jdbc/myDB");
           ...


          A few notes:

          - The JNDI name jdbc/myApp/myDB is arbitrary. I intentionally used myApp in the middle to make it different than the resource reference name jdbc/myDB used in EJBs.

          - The JNDI name of the data source is declared in mysql-ds.xml. This name is referenced in jbosscmp-jdbc.xml and jboss.xml with the java:/ prefix.

          - The JNDI name can be used in the code, but in that case any change to it would necessitate updating the Java code. By using resource reference names we insulate the code from changes in the JNDI names, as the binding from the resource reference name to the actual JNDI name is done in jboss.xml.

          Thanks,
          Alex