Tutorial

Tomcat DataSource JNDI Example in Java

Published on August 3, 2022
author

Pankaj

Tomcat DataSource JNDI Example in Java

Welcome to Tomcat DataSource JNDI Example Tutorial. We looked at the JDBC DataSource in the last tutorial and learned how to use that in standalone java application.

Tomcat DataSource JNDI

tomcat datasource, jndi example, tomcat jndi, jndi tutorial Actual benefit of DataSource comes when we use it with a JNDI Context. For example, connection pool in a web application deployed in a servlet container. Most of the popular servlet containers provide built-in support for DataSource through Resource configuration and JNDI context. This helps us in creating and using DataSource connection pool with just few lines of configuration. This tutorial is aimed to provide Tomcat DataSource JNDI configuration example. Apache Tomcat provide three ways to configure DataSource in JNDI context.

  1. Application context.xml - This is the easiest way to configure DataSource, all we need is a context.xml file in META-INF directory. We have to define Resource element in the context file and container will take care of loading and configuring it. The approach is simple but it has some drawbacks;
    • Since the context file is bundled with the WAR file, we need to build and deploy new WAR for every small configuration change. Same issue comes if your application works in distributed environment or your application needs to be deployed in different testing environments such as QA, IT, PROD etc.
    • The datasource is created by container for the application usage only, so it can’t be used globally. We can’t share the datasource across multiple applications.
    • If there is a global datasource (server.xml) defined with same name, the application datasource is ignored.
  2. Server context.xml - If there are multiple applications in the server and you want to share DataSource across them, we can define that in the server context.xml file. This file is located in apache-tomcat/conf directory. The scope of server context.xml file is application, so if you define a DataSource connection pool of 100 connections and there are 20 applications then the datasource will be created for each of the application. This will result in 2000 connections that will obviously consume all the database server resources and hurt application performance.
  3. server.xml and context.xml - We can define DataSource at global level by defining them in the server.xml GlobalNamingResources element. If we use this approach, then we need to define a ResourceLink from context.xml file of server or application specific. This is the preferred way when you are looking to share a common resource pool across multiple applications running on the server. Regarding resource link, whether to define it at server level context xml file or application level depends on your requirement.

Let’s head over to the Tomcat DataSource JNDI example in java web application. For the test data setup, please refer to my last article about JDBC DataSource Example.

Tomcat DataSource JNDI Configuration Example - server.xml

Add below code in the tomcat server.xml file. The code should be added in the GlobalNamingResources element. Also make sure that database driver is present in the tomcat lib directory, so in this case mysql jdbc jar have to be present in the tomcat lib.

<Resource name="jdbc/MyDB" 
      global="jdbc/MyDB" 
      auth="Container" 
      type="javax.sql.DataSource" 
      driverClassName="com.mysql.jdbc.Driver" 
      url="jdbc:mysql://localhost:3306/UserDB" 
      username="pankaj" 
      password="pankaj123" 
      
      maxActive="100" 
      maxIdle="20" 
      minIdle="5" 
      maxWait="10000"/>

Here we are creating JNDI context with name as jdbc/MyDB which is a type of DataSource. We are passing database configurations in url, username, password and driverClassName attribute. Connection pooling properties are defined in maxActive, maxIdle and minIdle attributes.

Add below code in the server context.xml file.

<ResourceLink name="jdbc/MyLocalDB"
                global="jdbc/MyDB"
                auth="Container"
                type="javax.sql.DataSource" />

Notice that resource link name is different than global link, we have to use this name in our java program to get the DataSource.

Tomcat DataSource JNDI Example

Create a dynamic web application with name JDBCDataSourceTomcat and then create a Servlet with below code.

package com.journaldev.jdbc.datasource;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

@WebServlet("/JDBCDataSourceExample")
public class JDBCDataSourceExample extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Context ctx = null;
		Connection con = null;
		Statement stmt = null;
		ResultSet rs = null;
		try{
			ctx = new InitialContext();
			DataSource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/MyLocalDB");
			
			con = ds.getConnection();
			stmt = con.createStatement();
			
			rs = stmt.executeQuery("select empid, name from Employee");
			
			PrintWriter out = response.getWriter();
            response.setContentType("text/html");
            out.print("<html><body><h2>Employee Details</h2>");
            out.print("<table border=\"1\" cellspacing=10 cellpadding=5>");
            out.print("<th>Employee ID</th>");
            out.print("<th>Employee Name</th>");
            
            while(rs.next())
            {
                out.print("<tr>");
                out.print("<td>" + rs.getInt("empid") + "</td>");
                out.print("<td>" + rs.getString("name") + "</td>");
                out.print("</tr>");
            }
            out.print("</table></body><br/>");
            
            //lets print some DB information
            out.print("<h3>Database Details</h3>");
            out.print("Database Product: "+con.getMetaData().getDatabaseProductName()+"<br/>");
            out.print("Database Driver: "+con.getMetaData().getDriverName());
            out.print("</html>");
            
		}catch(NamingException e){
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			try {
				rs.close();
				stmt.close();
				con.close();
				ctx.close();
			} catch (SQLException e) {
				System.out.println("Exception in closing DB resources");
			} catch (NamingException e) {
				System.out.println("Exception in closing Context");
			}
			
		}
	}

}

Notice that I am using Servlet 3 Annotation based configuration and it will work in Tomcat 7 or higher versions. If you are using lower version of Tomcat then you need to do some modifications to the servlet code, to remove WebServlet annotation and configure in web.xml file. The part of servlet code that we are interested in;

ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/MyLocalDB");

This is the way to get the JNDI resources defined to be used by the application. We could have written it in this way too;

ctx = new InitialContext();
Context initCtx  = (Context) ctx.lookup("java:/comp/env");
DataSource ds = (DataSource) initCtx.lookup("jdbc/MyLocalDB");

I am also printing some database information to check which database we are connected. Now when you will run the application, you will see following output. Tomcat DataSource JNDI Example MySQL, JNDI DataSource MySQL Let’s see how easy it is to switch the database server because we are using Tomcat DataSource. All you need is to change the Database properties. So if we have to switch to Oracle database, my Resource configuration will look like below.

<Resource name="jdbc/MyDB" 
      global="jdbc/MyDB" 
      auth="Container" 
      type="javax.sql.DataSource" 
      driverClassName="oracle.jdbc.driver.OracleDriver" 
      url="jdbc:oracle:thin:@localhost:1521:orcl" 
      username="hr" 
      password="oracle" 
      
      maxActive="100" 
      maxIdle="20" 
      minIdle="5" 
      maxWait="10000"/>

And when we restart the server and run the application, it will connect to Oracle database and produce below result. Tomcat DataSource JNDI Example Oracle That’s all for Tomcat DataSource JNDI configuration example tutorial, you can define the resource in similar way in context.xml files too.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author(s)

Category:
Tutorial

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
February 3, 2014

nice post…and where did u get this path java:/comp/env

- subbareddy

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    March 1, 2014

    good explanation…

    - Arun

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      March 27, 2014

      Excellent post………………Could you please explain how you get this " java:/comp/env"… Sorry I am kind of beginner in Java language. Thanking in advance. regards, Zulifqar

      - Zulifqar

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      March 27, 2014

      java:comp/env is the root node of JNDI tree from where we can lookup specific JNDI contexts.

      - Pankaj

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        May 1, 2014

        THanks for the post, but I am getting Error: Java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.BasicDataSource cannot be cast to sun.jdbc.odbc.ee.DataSource can you please help

        - Anshul Jain

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        October 15, 2014

        Wrong import lib

        - Oleg

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          June 2, 2014

          Hi sir,i created a datasource in Server.xml and writing resourcelink in context.xml but it is not considering second Database Connection Details sir. in Server.xml under GlobalNamingResources tag i wrote 2 Resource tags for 2 different db connections and in Context.xml i wrote 2 ResourceLink for those 2 different db connections, First Connection is working where as second one is not working sir.

          - Venkata Sriram

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            June 13, 2014

            i do not understand this sir plz explain where it is …“java:/comp/env/jdbc/MyLocalDB”

            - lalit

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            September 30, 2014

            Seems it’s typo. Use jdbc/MyDB instead

            - Denn

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              June 25, 2014

              I have put in server context.xml. but i have put following tag in the web.xml DB Connection jdbc/MoranDB javax.sql.DataSource Container ============== i am able to use the Datasource connection. But i want to know the difference between using (server.xml and context.xml) and as i do(context.xml of server and web.xml of application). PS: i am using tomcat-7 and Mysql database. please give you insight. thank you

              - irshad

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              June 25, 2014

              DB Connection jdbc/MoranDB javax.sql.DataSource Container

              - irshad

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                July 19, 2014

                Thanks for the post. I read a lot of blogs, and everywhere I saw only the configuration in Server.xml file. I was trying to following the same thing but it never worked, after looking at your explanation, I added the elements in Context.xml and it worked like a charm. Thanks again, brother.

                - pradeep

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  October 12, 2014

                  Thanks a lot for this really clear example.

                  - Ju

                    JournalDev
                    DigitalOcean Employee
                    DigitalOcean Employee badge
                    October 15, 2014

                    Thank for great tutorials. I have problem with this one. It doesn’t show me table, it just show message “TODO write content”. What can be wrong?

                    - Oleg

                      JournalDev
                      DigitalOcean Employee
                      DigitalOcean Employee badge
                      October 21, 2014

                      Thank you Pankaj for this useful article, But I wold like to add regarding Eclipse Don’t forget that the Tomcat files will be under the “Server” in the eclipse project hierarchy so modifying them in tomcat alone will not help thank you again

                      - Ali Saleh

                        JournalDev
                        DigitalOcean Employee
                        DigitalOcean Employee badge
                        November 19, 2014

                        nice post.Very helpful

                        - Pavan

                          JournalDev
                          DigitalOcean Employee
                          DigitalOcean Employee badge
                          November 22, 2014

                          Nice article. Thank You.

                          - Punnoose

                            JournalDev
                            DigitalOcean Employee
                            DigitalOcean Employee badge
                            February 13, 2015

                            THANK YOU SO MUCH for this post, I had problems to understand this JNDI stuff, I didn’t know anything about JNDI and know everything is clear! Thanks Pankaj :)

                            - Jorge de Lemos

                              JournalDev
                              DigitalOcean Employee
                              DigitalOcean Employee badge
                              February 18, 2015

                              Sir,I would like to know about my project . regarding the connection of servlet code to telegram web for bus booking through online

                              - Jeevitha

                                JournalDev
                                DigitalOcean Employee
                                DigitalOcean Employee badge
                                March 16, 2015

                                This is my first time i’m commenting on the web, because it really works and the article is really great.

                                - Sam

                                  JournalDev
                                  DigitalOcean Employee
                                  DigitalOcean Employee badge
                                  April 28, 2015

                                  Great article, very helpful. Thanks!

                                  - Kamil

                                    JournalDev
                                    DigitalOcean Employee
                                    DigitalOcean Employee badge
                                    June 10, 2015

                                    Hi All, I have following configuration… – main-context.xml --DataSource.xml WEB-INF/database.properties Instead of above definition I have used following definition --database.properties jdbc.jndiName=java:comp/env/jdbc/MYAPPDB --server.xml I have encrypted datasource password using BASE64Encoder Here is my EncryptedDataSource class for decrypting password which extends JndiObjectFactoryBean package my.app.util; import java.io.IOException; import javax.naming.NamingException; import org.apache.commons.configuration.JNDIConfiguration; import org.springframework.jndi.JndiObjectFactoryBean; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; public class EncryptedDataSource extends JndiObjectFactoryBean{ /*@Override public String getPassword() { String password = super.getPassword(); password = decode(password); return password; }*/ private String decode(String decode) { BASE64Decoder decoder = new BASE64Decoder(); try { decode = new String(decoder.decodeBuffer(decode)); } catch (IOException e) { e.printStackTrace(); } return decode; } private String encode(String encode) throws IOException { BASE64Encoder encoder = new BASE64Encoder(); encode = new String(encoder.encodeBuffer(encode.getBytes())); return encode; } public static void main(String[] args) throws IllegalArgumentException, NamingException { EncryptedDataSource ed = new EncryptedDataSource(); try { String password = ed.encode(“password”); System.out.println("password = "+password); } catch (IOException e) { e.printStackTrace(); } } } I want to decrypt while connection pooling. Please help.

                                    - Yatin

                                      JournalDev
                                      DigitalOcean Employee
                                      DigitalOcean Employee badge
                                      June 14, 2015

                                      Hello, I have an error when I run this example. org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class ‘’ for connect URL ‘null’. I can’t find any solution in google :( Pls help me.

                                      - Dmitry

                                        JournalDev
                                        DigitalOcean Employee
                                        DigitalOcean Employee badge
                                        August 14, 2015

                                        Hi, Great article, very helpful… But I have a doubt, which is a difference beetween: java:comp/env/jdbc/name_ds java:/comp/env/jdbc/name_ds java:jdbc/name_ds java:/jdbc/name_ds where can I setup the way to call the jndi? I have this problem, in my pc an example works with “java:/comp/env/jdbc/name_ds”, the same example in the my friend computer doesn’t work, we changed to “java:/jdbc/name_ds” to work. We don’t know what is the reason… Anybody can help us? Thanks

                                        - Atelo

                                          Try DigitalOcean for free

                                          Click below to sign up and get $200 of credit to try our products over 60 days!

                                          Sign up

                                          Join the Tech Talk
                                          Success! Thank you! Please check your email for further details.

                                          Please complete your information!

                                          Become a contributor for community

                                          Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                                          DigitalOcean Documentation

                                          Full documentation for every DigitalOcean product.

                                          Resources for startups and SMBs

                                          The Wave has everything you need to know about building a business, from raising funding to marketing your product.

                                          Get our newsletter

                                          Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

                                          New accounts only. By submitting your email you agree to our Privacy Policy

                                          The developer cloud

                                          Scale up as you grow — whether you're running one virtual machine or ten thousand.

                                          Get started for free

                                          Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

                                          *This promotional offer applies to new accounts only.