Search code examples
javatomcatdatasourcejnditomcat7

Unable to access database after upgrading from Tomcat 5.0.27 to Tomcat 7.0.30


To solve another issue I need to replace my rather old tomcat 5 installation with a tomcat 7 installtion. My application connects to a database using a datsource defined in the applications context.xml. But after moving to Tomcat 7 although my code for getting a datasource seems to work without error (it doesnt throw an exception or return null)

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

an attempt to get connection fails:

getDataSource.getConnection()

it fails with

   org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
            at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1452)
            at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1371)
            at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
            at com.jthink.appserver.jaikoz.util.db.DBManager.getConnection(DBManager.java:92)
com.jthink.appserver.jaikoz.action.Check.handleRequest(CheckVersion2.java:145)
            at com.jthink.appserver.jaikoz.Session.run(Session.java:66)
            at com.jthink.appserver.jaikoz.Controller.doTask(Controller.java:68)
            at com.jthink.appserver.jaikoz.Controller.doGet(Controller.java:61)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
            at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
            at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
            at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
            at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
            at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
            at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
            at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
            at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
            at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
            at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
            at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
            at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
            at java.lang.Thread.run(Thread.java:619)
    Caused by: java.lang.NullPointerException
            at sun.jdbc.odbc.JdbcOdbcDriver.getProtocol(JdbcOdbcDriver.java:507)
            at sun.jdbc.odbc.JdbcOdbcDriver.knownURL(JdbcOdbcDriver.java:476)
            at sun.jdbc.odbc.JdbcOdbcDriver.acceptsURL(JdbcOdbcDriver.java:307)
            at java.sql.DriverManager.getDriver(DriverManager.java:253)
            at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1437)

I'm wondering if a> something works differently on tomcat7 or b> I've forgotten to do something. This is what I did:

Copy all webapps from tomcat5 to tomcat7
Copy jaikoz.xml file from Conf/Catalina/localhost to tomcat7
Copy common/lib/mysql-connector-java-3.1.4-beta-bin.jar into webapps/jaikoz/WEB-INF/lib

There doesn't seem to be a commons folder on tomcat5 so I've just put the mysql jar into the applications war, but maybe that is wrong

My jaikoz.xml file is

<Context path="/jaikoz" displayname="jaikoz" docBase="../webapps/jaikoz" debug="0" privileged="true">

<Resource name="jdbc/jaikoz"
            auth="Container"
            type="javax.sql.DataSource"/>

  <ResourceParams name="jdbc/jaikoz">
    <parameter>
      <name>factory</name>
      <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
    </parameter>

    <!-- Maximum number  of dB connections in pool. Make sure you
         configure your mysqld max_connections large enough to handle
         all of your db connections. Set to 0 for no limit.
         -->
    <parameter>
      <name>maxActive</name>
      <value>0</value>
    </parameter>

    <!-- Maximum number of idle dB connections to retain in pool.
         Set to 0 for no limit.
         -->
    <parameter>
      <name>maxIdle</name>
      <value>0</value>
    </parameter>

    <!-- Maximum time to wait for a dB connection to become available
         in ms, in this example 10 seconds. An Exception is thrown if
         this timeout is exceeded.  Set to -1 to wait indefinitely.
         -->
    <parameter>
      <name>maxWait</name>
      <value>10000</value>
    </parameter>

    <!-- MySQL dB username and password for dB connections  -->
    <parameter>
     <name>username</name>
     <value>********</value>
    </parameter>

    <parameter>
     <name>password</name>
     <value>**********</value>
    </parameter>

    <!-- Class name for mm.mysql JDBC driver -->
    <parameter>
      <name>driverClassName</name>
      <value>com.mysql.jdbc.Driver</value>      
    </parameter>

    <!-- The JDBC connection url for connecting to your MySQL dB.
         The autoReconnect=true argument to the url makes sure that the
         mm.mysql JDBC Driver will automatically reconnect if mysqld closed the
         connection.  mysqld by default closes idle connections after 8 hours.
         -->
    <parameter>
      <name>url</name>
      <value>jdbc:mysql://localhost:3306/jaikoz?autoReconnect=true</value>
    </parameter>
  </ResourceParams>

</Context>

Solution

  • It looks like you have another JDBC driver found on the classpath: the ODBC driver (sun.jdbc.odbc.JdbcOdbcDriver). Obviously it doesn't like the MySQL JDBC URL, so you should remove it. It might be installed either in Tomcat itself, or in your application.

    Besides, your MySQL JDBC driver looks like a old one (mysql-connector-java-3.1.4-beta-bin.jar). The current version of the driver is 5.1.22, or 3.1.14 for the 3.1 series. You may want to upgrade, especially if you're connecting to a more recent version of MySQL than 3.1.