views:

82

answers:

1

I'm getting this error when I try to view the page:

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

I have the following /WEB-INF/web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
    <display-name>WSwartzendruber.net</display-name>
    <description>Personal Website</description>
    <!-- Servlet stuff -->
    <servlet>
        <servlet-name>PostgresTest</servlet-name>
        <servlet-class>PostgresTest</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>PostgresTest</servlet-name>
        <url-pattern>/servlets/postgrestest</url-pattern>
    </servlet-mapping>
    <!-- JNDI -->
    <resource-ref>
        <description>PostgreSQL Data Source</description>
        <res-ref-name>jdbc/db_website</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
</web-app>

I have this in /META-INF/context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Context reloadable="true">
    <Resource name="jdbc/db_website" auth="Container" type="javax.sql.DataSource" driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/db_website" username="website"/>
</Context>

And here is the test code:

import java.io.*;
import java.sql.*;
import javax.naming.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.sql.*;
import org.wswartzendruber.website.access.*;

public class PostgresTest extends HttpServlet
{
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
    {
        response.setContentType("text/plain");

        try
        {
            Context initialContext = new InitialContext();
            Context context = (Context)initialContext.lookup("java:comp/env");
            DataSource dataSource = (DataSource)context.lookup("jdbc/db_website");
            Connection connection = dataSource.getConnection();
            NewsCategory[] newsCategory = NewsCategory.getNewsCategories(connection);

            connection.close();
        }
        catch (NamingException e)
        {
            response.getWriter().println("ERROR: We have naming problems!");
        }
        catch (SQLException se)
        {
            response.getWriter().println("ERROR: SQLException: " + se.getMessage());
        }
        catch (AccessException ae)
        {
            response.getWriter().println("ERROR: AccessException: " + ae.getMessage());
        }
    }
}

I'm at a loss for what the issue is. I already have /usr/share/tomcat-6/lib/postgresql-8.4-702.jdbc4.jar in place. Moving it to /WEB-INF/lib makes no difference. It seems to me that it can see the resource entry in WEB-INF/web.xml, but that it can't pull the details from META-INF/context.xml. Assigning a password there also seems to make no difference.

I'm up for whatever you guys have.


Update: here is the full stacktrace:

Sep 19, 2010 7:01:36 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet PostgresTest threw exception
java.io.IOException: org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
    at PostgresTest.doGet(PostgresTest.java:23)
    at javax.servlet.http.HttpServlet.service(Unknown Source)
    at javax.servlet.http.HttpServlet.service(Unknown Source)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Unknown Source)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(Unknown Source)
    at org.apache.catalina.core.StandardWrapperValve.invoke(Unknown Source)
    at org.apache.catalina.core.StandardContextValve.invoke(Unknown Source)
    at org.apache.catalina.core.StandardHostValve.invoke(Unknown Source)
    at org.apache.catalina.valves.ErrorReportValve.invoke(Unknown Source)
    at org.apache.catalina.core.StandardEngineValve.invoke(Unknown Source)
    at org.apache.catalina.connector.CoyoteAdapter.service(Unknown Source)
    at org.apache.jk.server.JkCoyoteHandler.invoke(Unknown Source)
    at org.apache.jk.common.HandlerRequest.invoke(Unknown Source)
    at org.apache.jk.common.ChannelSocket.invoke(Unknown Source)
    at org.apache.jk.common.ChannelSocket.processConnection(Unknown Source)
    at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(Unknown Source)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:636)
Caused by: 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 PostgresTest.doGet(PostgresTest.java:17)
    ... 17 more
Caused by: java.lang.NullPointerException
    at org.postgresql.Driver.parseURL(Driver.java:567)
    at org.postgresql.Driver.acceptsURL(Driver.java:412)
    at java.sql.DriverManager.getDriver(DriverManager.java:268)
    at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1437)
    ... 20 more
+1  A: 

The "caused by"/"root cause" part of the exception contains information about why it has failed. You should not print only the exception message and ignore the remnant of the exception detail. You should throw the entire exception or at least print the entire stacktrace.

A quick fix: replace your try by

try {
    Context initialContext = new InitialContext();
    Context context = (Context)initialContext.lookup("java:comp/env");
    DataSource dataSource = (DataSource)context.lookup("jdbc/db_website");
    Connection connection = dataSource.getConnection();
    NewsCategory[] newsCategory = NewsCategory.getNewsCategories(connection);
    connection.close();
} catch (Exception e) {
    throw new ServletException(e);
}

And retry. The whole stacktrace should show up in the server's default error page. Or if you have customized the error page that it doesn't show the trace, then look in the server logs, it's there as well.


Update as per the comment: You could just add ServletException to the throws clause. According to the stacktrace, the resource in context.xml is correctly located, the driver is correctly loaded, but the URL has not been passed in as if it's not been specified in the <Resource>.

Are you sure that you're supplying the <Resource> you think you're supplying? Don't you have another <Resource> with the same name, but without an url in Tomcat/conf/context.xml?

BalusC
I had to make it throw an IOException instead, but here's the server log: http://pastebin.com/00tazRnQ
See the update in the answer.
BalusC