Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JNDI path Tomcat vs. Jboss

I have DataSource which is configured on Tomcat 6 in context.xml as MyDataSource. And I'm fetching it the following way:

      DataSource dataSource;
            try {
                dataSource = (DataSource) new InitialContext().lookup("java:comp/env/MyDataSource");
            } catch (NamingException e) {
                throw new DaoConfigurationException(
                    "DataSource '" + url + "' is missing in JNDI.", e);
            }

Everything works fine. Now I'm exporting this code to Jboss AP 6. and I configured my dataSource and its connection pool as local-tx dataSource under the same name.

When I'm executing the code above, I'm getting NamingException exception. after some investigation I've found that correct way to call my DataSource under Jboss is

 dataSource = (DataSource) new InitialContext().lookup("java:/MyDataSource");

Can anybody explain me why should I omit "comp/env" in my JNDI path under Jboss?

like image 540
danny.lesnik Avatar asked Aug 28 '11 21:08

danny.lesnik


People also ask

Does JBoss supports JNDI?

Introduction. JBoss Web provides a JNDI InitialContext implementation instance for each web application running under it, in a manner that is compatible with those provided by a Java2 Enterprise Edition application server. The J2EE standard provides a standard set of elements in the /WEB-INF/web.

What is JNDI name in JBoss?

The JBoss naming service is an implementation of the Java Naming and Directory Interface (JNDI). JNDI plays a key role in J2EE because it provides a naming service that allows a user to map a name onto an object.

How is Jndi defined?

The Java Naming and Directory Interface™ (JNDI) is an application programming interface (API) that provides naming and directory functionality to applications written using the Java™ programming language. It is defined to be independent of any specific directory service implementation.


2 Answers

The portable approach for defining data sources is to use a resource reference. Resource references enable you to define the JNDI name for your data source, relative to your application naming context (java:comp/env), and then map that logical reference to the physical resource defined in the application server, whose JNDI name is proprietary to the application server vendor. This approach enables your code and assembly to be portable to any compliant application server.

Step 1: Declare and Lookup Resource Reference

Option 1

This can be done by declaring a resource-ref in your web deployment descriptor (WEB-INF/web.xml):

<resource-ref>
    <description>My Data Source.</description>
    <res-ref-name>jdbc/MyDataSource</res-ref-name> 
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

Within your code, you can then lookup this resource using the JNDI name java:comp/env/jdbc/MyDataSource:

dataSource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/MyDataSource");

This JNDI name will not change regardless of the server where the application is deployed.

Option 2

Alternatively, starting in Java EE 5 (Servlet 2.5), this can be done even easier within your code using the @Resource annotation. This eliminates the need for configuring the resource-ref in your web deployment descriptor (web.xml) and prevents the need to perform an explicit JNDI lookup:

public class MyServlet extends HttpServlet {

    @Resource(name = "jdbc/MyDataSource")
    private DataSource dataSource;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // dataSource may be accessed directly here since the container will automatically
        // inject an instance of the data source when the servlet is initialized

}

This approach has the same results as the previous option, but cuts down on the boilerplate code and configuration in your assembly.

Step 2: Map Resource Reference to Data Source

Then, you will need to use your application server's proprietary approach for mapping the resource reference to the physical data source that you created on the server, for example, using JBoss's custom deployment descriptors (WEB-INF/jboss-web.xml):

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
    <resource-ref>
        <res-ref-name>jdbc/MyDataSource</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <jndi-name>java:/MyDataSource</jndi-name>
    </resource-ref>
</jboss-web>

Or, for example, using Tomcat's context.xml:

<Resource name="jdbc/MyDataSource" . . . />
like image 77
shelley Avatar answered Oct 14 '22 19:10

shelley


You can add to your data source definition the 'jndi-name' tag:

jndi-name - the JNDI name under which the DataSource should be bound.

You can find data source documentation on JBoss wiki: ConfigDataSources

like image 41
Lukasz Stelmach Avatar answered Oct 14 '22 20:10

Lukasz Stelmach