Tomcat DBCP error: Cannot create JDBC driver of class ... for connect URL null

I just ran into a crazy error related to Tomcat and DBCP connection pooling. The error message I got after trying to use the Tomcat DBCP connection pooling in my Java web application was:

Cannot create JDBC driver of class '' for connect URL 'null'

I was trying to deploy my web app with a context.xml file in the META-INF directory of my web application, and I did everything else according to the Tomcat instructions, but I still got that error message. Fortunately after a little research I was able to solve this problem.

Why it's failing

I'm trying to deploy a Java application I've named "nagios", but instead of actually deploying my application using a WAR file named nagios.war, I was just trying to make a couple of small changes to my web application manually, basically shutting down Tomcat, making a few tweaks to switch over to DBCP connection pooling, and then restarting Tomcat. For a variety of reasons it was going to be a real pain to build a WAR file, and I thought I'd get away with a little surgical strike.

I'm about 99% sure that what's happening is that Tomcat is expecting me to deploy my application as a WAR file, and during this normal/expected deployment scenario, Tomcat would take the META-INF/context.xml file out of my WAR file, and copy it to this location:

${CATALINA_HOME}/conf/Catalina/localhost/nagios.xml

(Note that in that path, the filename created by Tomcat (nagios.xml in my example) is really [your-app-name].xml.)

So, because I'm not going through this normal WAR-based deployment process, Tomcat doesn't have the chance to copy my META-INF/context.xml to that location, so my code that is trying to use the DBCP connection pooling is failing with the "cannot create JDBC driver of class ... null".

The solution

Now that I understand the problem, there are several possible solutions. The easiest one for me today is to manually place my context.xml file in the ${CATALINA_HOME}/conf/Catalina/localhost directory, renamed it to nagios.xml in the process.

There's not much to say, other than I just did this, restarted my Tomcat instance, and verified that it works.

My sample context.xml file

For the purpose of completeness I thought I'd include my context.xml file here. There's not too much to say about it, other than it uses the Tomcat DBCP connection pooling functionality, and it's used to help create a connection pool for a Postgres database. The connection pool is made available to my application using the JNDI name jdbc/postgres.

<?xml version="1.0" encoding="UTF-8"?>

<!-- the new database connection pooling stuff -->
<!-- see: http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto.html -->

<Context path="/nagios" docBase="nagios" crossContext="true" reloadable="true" debug="1">

  <Resource name="jdbc/postgres" auth="Container"
            type="javax.sql.DataSource"
            driverClassName="org.postgresql.Driver"
            url="jdbc:postgresql://localhost/nagios"
            username="nagiosuser"
            password="nagiospassword"
            maxActive="10"
            maxIdle="5"
            maxWait="-1"
            removeAbandoned="true"
            removeAbandonedTimeout="60"
            logAbandoned="true"
            />

</Context>