title: JDBC data source not working when project deployed on tomcat
body: <p>I have developed a servlet which calls a MariaDB database through a JDNI datasource. This works fine when I run the web project within eclipse on a tomcat server run within eclipse.</p>
  
  <p>However, when I deploy the project on a tomcat server outside eclipse, using a WAR file, the same servlet does not work. For testing purposes, the project also contains another servlet that connect directly (i.e. not using the JDNI datasource) to the same mariaDB and it works fine even when deployed to tomcat server outside eclipse.
  I am running out of ideas concerning what could possibly be wrong and would greatly appreciate if someone could shed some light.</p>
  
  <p>Configuration information:</p>
  
  <ul>
  <li>OS : macOS High Sierra</li>
  <li>tomcat version : 8.5</li>
  <li>eclipse : Neon.2., release 4.6.2</li>
  <li>Java : 8</li>
  <li>MariaDB driver : mariadb-java-client-2.2.0</li>
  </ul>
  
  <p>Outiside eclipse, The driver is in two locations:</p>
  
  <ul>
  <li>/tomcat-folder/lib</li>
  <li>/tomcat-folder/webapps/my-app/WEB-INF/lib (from the WAR file)</li>
  </ul>
  
  <p>I have added the following resource reference to the application web.xml file:</p>
  
  <pre><code>&lt;resource-ref&gt;
      &lt;description&gt;DB Connection&lt;/description&gt;
      &lt;res-ref-name&gt;jdbc/MYDB&lt;/res-ref-name&gt;
      &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
      &lt;res-auth&gt;Container&lt;/res-auth&gt;
  &lt;/resource-ref&gt;
  </code></pre>
  
  <p>I have added the following resource to /tomcat-folder/contf/context.xml:</p>
  
  <pre><code>&lt;Resource name="jdbc/MYDB” auth="Container" type="javax.sql.DataSource"
                 maxTotal="100" maxIdle="30" maxWaitMillis="10000"
                 username="root" password="" driverClassName="org.mariadb.jdbc.Driver"
                 url="jdbc:mariadb//localhost:3306/MYDB”/&gt;
  </code></pre>
  
  <p>The error I get is :</p>
  
  <pre><code>java.sql.SQLException: Cannot create JDBC driver of class 'org.mariadb.jdbc.Driver' for connect URL 'jdbc:mariadb//localhost:3306/MYDB'
      at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createConnectionFactory(BasicDataSource.java:2167)
      at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:2037)
      at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1543)
      at DBConfigTest.getConnection(DBConfigTest.java:123)
      at DBConfigTest.doGet(DBConfigTest.java:59)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
      at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
      at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
      at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
      at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
      at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:789)
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1437)
      at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:745)
  Caused by: java.sql.SQLException: No suitable driver
      at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createConnectionFactory(BasicDataSource.java:2158)
      ... 28 more
  java.lang.NullPointerException
      at DBConfigTest.doGet(DBConfigTest.java:61)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
      at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
      at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
      at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
      at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
      at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:789)
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1437)
      at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:745)
  </code></pre>
  
  <p>the servlet code is as follows:</p>
  
  <pre><code>import java.io.*;
  import javax.servlet.*;
  import javax.servlet.http.*;
  import java.sql.*;
  import javax.naming.InitialContext;
  import javax.naming.Context;
  import javax.naming.NamingException;
  import javax.sql.DataSource;
  
  public class DBConfigTest extends HttpServlet{
     public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
  
        // JDBC driver name and database URL
       // static final String JDBC_DRIVER = "org.mariadb.jdbc.Driver";  
       // static final String DB_URL="jdbc:mariadb://localhost/MYDB"+"?user=root&amp;password=";
  
        //  Database credentials
       // static final String USER = "root";
       // static final String PASS = "";
  
        // Set response content type
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        String title = "Database Result";
  
        String docType =
           "&lt;!doctype html public \"-//w3c//dtd html 4.0 " + "transitional//en\"&gt;\n";
  
        out.println(docType +
           "&lt;html&gt;\n" +
           "&lt;head&gt;&lt;title&gt;" + title + "&lt;/title&gt;&lt;/head&gt;\n" +
           "&lt;body bgcolor = \"#f0f0f0\"&gt;\n" +
           "&lt;h1 align = \"center\"&gt;" + title + "&lt;/h1&gt;\n");
  
     // Execute SQL query
        //Statement stmt=null;
        //Connection conn=null;
        Connection connection=null;
        PreparedStatement statement=null;
  
        try {
           // Register JDBC driver
           //Class.forName("org.mariadb.jdbc.Driver");
  
           // Open a connection
           //conn = DriverManager.getConnection("jdbc:mariadb://localhost/MYDB"+"?user=root&amp;password=");
  
                  connection = getConnection();
                String sql = "SELECT * FROM  ingredient";
                statement = connection.prepareStatement(sql);
                ResultSet rs = statement.executeQuery();
  
           // Execute SQL query
           /*stmt = conn.createStatement();
           String sql;
           sql = "SELECT * FROM  ingredient";
           ResultSet rs = stmt.executeQuery(sql);*/
  
           // Extract data from result set
           while(rs.next()){
              //Retrieve by column name
              int id  = rs.getInt("ingredient_id");
              String code = rs.getString("ingredient_code");
              String description = rs.getString("ingredient_description");
  
              //Display values
              out.println("ID: " + id + "&lt;br&gt;");
              out.println(", Code: " + code + "&lt;br&gt;");
              out.println(", Description: " + description + "&lt;br&gt;");
  
           }
           out.println("&lt;/body&gt;&lt;/html&gt;");
  
           // Clean-up environment
           rs.close();
           statement.close();
           connection.close();
        } catch(SQLException se) {
           //Handle errors for JDBC
           se.printStackTrace();
        } catch(Exception e) {
           //Handle errors for Class.forName
           e.printStackTrace();
        } finally {
           //finally block used to close resources
           try {
              if(statement!=null)
                 statement.close();
           } catch(SQLException se2) {
           } // nothing we can do
           try {
              if(connection!=null)
              connection.close();
           } catch(SQLException se) {
              se.printStackTrace();
           } //end finally try
        } //end try
     }
  
  
  
     private Connection getConnection() {
          Connection connection = null;
          try {
            /*InitialContext context = new InitialContext();
            DataSource dataSource = (DataSource) context.lookup("jdbc/MYDB");
            connection = dataSource.getConnection();*/
  
              Context initContext = new InitialContext();
              Context envContext  = (Context)initContext.lookup("java:/comp/env");
              DataSource ds = (DataSource)envContext.lookup("jdbc/MYDB");
              connection = ds.getConnection();
  
  
          } catch (NamingException e) {
            e.printStackTrace();
          } catch (SQLException e) {
            e.printStackTrace();
          }
          return connection;
        }
  }
  </code></pre>