Cannot create JDBC driver of class ' ' for connect URL 'null' : I do not understand this exception
Asked Answered
G

12

62

Why does it say null URL and gives a empty ' ' class in the exception when I have provided the database URL?

I am trying to connect to a derby database via a servlet while using Tomcat. When the servlet gets run, I get the following exceptions:

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 servlets.servlet_1.doGet(servlet_1.java:23) // ---> Marked the statement in servlet

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:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
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:100)
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:405)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
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)
... 24 more

Servlet :

package servlets;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.http.*;
import javax.servlet.*;
import javax.sql.DataSource;

public class servlet_1 extends HttpServlet {

    @Override 
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
           // String queryString = request.getQueryString();
            System.out.println("!!!!!!!!!!!!!!!!!!!");
            Context initContext = new InitialContext();
            Context envContext = (Context)initContext.lookup("java:comp/env");
            DataSource ds = (DataSource)envContext.lookup("jdbc/PollDatasource");
            Connection connection = ds.getConnection(); // -->LINE 23
            String sqlQuery = "select * from PollResult";
            PreparedStatement statement = connection.prepareStatement(sqlQuery);
            ResultSet set = statement.executeQuery();
            System.out.println("after the final statement");
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }
}

What exception is this? Why do I get this exception?

I have added the following tag in context.xml of Tomcat :

<Resource name="jdbc/PollDatasource" auth="Container" type="javax.sql.DataSource"
driverClassName="org.apache.derby.jdbc.EmbeddedDriver"
url="jdbc:derby://localhost:1527/poll_database;create=true"
username="suhail" password="suhail"
maxActive="20" maxIdle="10" maxWait="-1" />

and this in web.xml :

<resource-ref>
  <description>my connection</description>
  <res-ref-name>jdbc/PollDatasource</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

Where am I making a mistake?

Image that shows the database URL..

enter image description here

NOTE : After the answer by @Bryan Pendleton I changed the driver to org.apache.derby.jdbc.ClientDriver but I get the same exception.

Gillette answered 17/7, 2012 at 5:54 Comment(7)
I think the connect URL is missing.Thunderpeal
@SuhailGupta We get flags on questions indicating it's a duplicate. Sometimes we process them incorrectly. It happens. We fix it where we can and we fixed it here. There's no reason to comment on this issue anymore.Twelfth
Where is your JDBC driver .jar file located?Cl
@Christopher Schultz what do you actually mean by JDBC driver ? I have the driver to connect to the derby database inside the lib folder of tomcat.Gillette
I meant what I said: "where is your JDBC driver .jar file?" You say it is in Tomcat's lib directory. That's good. Do you have it anywhere else? Do you have an out-of-process Derby database? Derby is usually used in-process.Cl
@Christopher Schultz No,only inside the tomcat's lib folder. No,in process.Gillette
I got the exact same error message after I copied a db configuration from one project to another as is (no changes). The connection was fine, the JDBC driver was fine, the connection user/password was fine. The problem was the second project was calling a package/stored procedure that didn't exist. Very misleading error message.Putnem
B
40

I can't see anything obviously wrong, but perhaps a different approach might help you debug it?

You could try specify your datasource in the per-application-context instead of the global tomcat one.

You can do this by creating a src/main/webapp/META-INF/context.xml (I'm assuming you're using the standard maven directory structure - if not, then the META-INF folder should be a sibling of your WEB-INF directory). The contents of the META-INF/context.xml file would look something like:

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

<Context [optional other attributes as required]>

<Resource name="jdbc/PollDatasource" auth="Container"
          type="javax.sql.DataSource" driverClassName="org.apache.derby.jdbc.ClientDriver"
          url="jdbc:derby://localhost:1527/poll_database;create=true"
          username="suhail" password="suhail" maxActive="20" maxIdle="10" maxWait="-1"/>
</Context>

Obviously the path and docBase would need to match your application's specific details.

Using this approach, you don't have to specify the datasource details in Tomcat's context.xml file. Although, if you have multiple applications talking to the same database, then your approach makes more sense.

At any rate, give this a whirl and see if it makes any difference. It might give us a clue as to what is going wrong with your approach.

Better answered 21/7, 2012 at 0:42 Comment(6)
It made a difference ! Now I want to know what was going wrong when I added the Resource thing in Tomcat's context.xml ?Gillette
I need more information about your tomcat's context.xml. Where did you define the resource.Better
Remove path, docBase, and debug: these attributes are not legal in this situation.Cl
@Better I defined it in the context.xml inside the conf folder i.e conf/context.xmlGillette
Are you able to give us more of the context.xml file? There are a couple of places within the context.xml where you can define a datasource.Better
if i am specifying the user name and passwrod in my app. THen how it is secure????Adulteration
C
11

Several fixes:

  1. Use the right driver class name for your environment: if you are using an out-of-process Derby server, then you want ClientDriver (and need to use derbyclient.jar), the hostname and port, etc. If you want an in-process Derby server, then you want derby.jar, EmbeddedDriver, and a URL that is appropriate for an embedded database.

  2. Put your driver JAR file only in Tomcat's lib/ directory.

  3. Don't put anything in Tomcat's conf/context.xml: there's really no reason for it. Instead, use your webapp's META-INF/context.xml to define your <Resource>.

The error "Cannot create JDBC driver of class '' for connect URL 'null' usually occurs because the JDBC driver is not in the right place (or in too many places, like Tomcat's lib/ directory but also in the webapp's WEB-INF/lib/ directory). Please verify that you have the right driver JAR file in the right place.

Cl answered 22/7, 2012 at 21:23 Comment(12)
The driver has always been in the right place,that is inside the lib folder of tomcat.Gillette
@ChristopherSchultz The reason why resources are put to conf/context and not META-INF is platform independecy. You have just one war and more resource config and pooling managed by the given server.Alarcon
@Alarcon You can maintain platform independence without modifying Tomcat's site-wide conf/context.xml. Modifying that file is sloppy at best and a security vulnerability at worst.Cl
@ChristopherSchultz I'm using this to configure an Oracle Universal Connection Pool. When my app shuts down Tomcat complains that it left some UCP threads hanging. I'm not sure, but I assume if I could get it to work with conf/context.xml Tomcat wouldn't complain about this?Kliman
@Kliman Oracle's driver either has a bug in it, or you aren't properly shutting-down the JDBC driver before your application unloads. Have you put your driver .jar file in Tomcat's lib directory or into your application's WEB-INF/lib?Cl
@ChristopherSchultz in Tomcat's lib. The whole point of defining a resource like this is that it can be shared between applications/executions of a single application, right? Meaning that the application shouldn't be responsible for shutting it down?Kliman
@Kliman Many JDBC drivers do stupid things like capturing the thread class loader and storing them forever. In a servlet environment, this can lead to a ClassLoader-pinning memory leak. To get around these problems in JDBC drivers, you sometimes have to take action during webapp shutdown. I know for instance that MySQL's Connector/J has had ClassLoader-pinning issues for a long time, and MySQL doesn't seem to buy the arguments for not going what they're doing. So, the JDBC driver continues to be broken, and certain hacks are required in order to stop a web application cleanly.Cl
@ChristopherSchultz huh, thanks for the tip, I'm sure it would have taken me awhile to discover that!Kliman
Tips 3 resolved my issue. I was putting the database connection info in the conf/context.xmlHackery
@ChristopherSchultz, tip 2 resolved a similar issue I with the Oracle DB Driver. I had the driver jar not only in in Tomcat's lib directory but also in WEB-INF/lib. I spent 4 hours trying out different things yesterday but the damn thing just kept complaining about a empty '' class and null URL. This solved the issue in an instant, thanks !Clytemnestra
This solved my issue: - MySQL connector jar only in tomcat/lib, - META-INF/context.xml and web.xml to configure the dataSourceRoxanaroxane
If you inject the DataSource using a @Resourse annotation, make sure you specify a name for it, like @Resource(name="jdbc/myDataSource"). This solved my problem.Diplomate
N
7

These two things don't match:

driverClassName="org.apache.derby.jdbc.EmbeddedDriver"
url="jdbc:derby://localhost:1527/poll database;create=true"

If you are using the EmbeddedDriver, your URL should not contain network syntax.

Conversely, if you are using network syntax, you need to use the ClientDriver.

http://db.apache.org/derby/docs/10.8/getstart/rgsquck35368.html

Nanna answered 17/7, 2012 at 17:53 Comment(2)
"If you are using the EmbeddedDriver, your URL should not contain network syntax." Can you please tell the manner i should write the URL when using the EmbeddedDriverGillette
As per following tutorial: db.apache.org/derby/papers/DerbyTut/embedded_intro.html , URL should look like jdbc:derby:poll_database;create=true in case of EmbeddedDriverTowbin
S
7

I was getting this problem because I put context.xml into the wrong path:

./src/main/resources/META-INF/context.xml

The correct path was:

./src/main/webapp/META-INF/context.xml
Stauder answered 1/12, 2015 at 11:50 Comment(0)
D
3

If you are using eclipse, you should modify the context.xml, from the server project created in your eclipse package explorer. When using tomcat in eclipse it is the only one valid, the others are ignored or overwriten

Directly answered 25/11, 2013 at 9:50 Comment(0)
D
2

Context envContext = (Context)initContext.lookup("java:comp/env");

not:Context envContext = (Context)initContext.lookup("java:/comp/env");

Diddle answered 17/7, 2012 at 6:2 Comment(4)
that was a mistake ! Get the same exception after editing it. See the EditGillette
see your context.xml of tomcat: url="connection.url",need to edit url,if you do not know changed to what ,you can see this: db.apache.org/derby/docs/10.7/devguide/…Diddle
i changed to url="jdbc:derby:poll database" but get the same exceptionsGillette
if your database name is polldatabase ,edit url to this: url="jdbc:derby: //localhost:1527/polldatabse;create=true";Diddle
T
1

Did you try to specify resource only in context.xml

<Resource name="jdbc/PollDatasource" auth="Container" type="javax.sql.DataSource"
driverClassName="org.apache.derby.jdbc.EmbeddedDriver"
url="jdbc:derby://localhost:1527/poll_database;create=true"
username="suhail" password="suhail"
maxActive="20" maxIdle="10" maxWait="-1" />

and remove <resource-ref> section from web.xml?

In one project I've seen configuration without <resource-ref> section in web.xml and it worked.

It's an educated guess, but I think <resource-ref> declaration of JNDI resource named jdbc/PollDatasource in web.xml may override declaration of resource with same name in context.xml and the declaration in web.xml is missing both driverClassName and url hence the NPEs for that properties.

Towbin answered 19/7, 2012 at 14:9 Comment(1)
Tomcat version is not mentioned - could you please specify which version of Tomcat is used?Towbin
F
1

The problem could also come because of a lack of SQL driver in your Tomcat installation directory.

I had to had mysql-connector-java-5.1.23-bin.jar in apache-tomcat-9.0.12/lib/ folder.

https://dev.mysql.com/downloads/connector/j/

Forehead answered 16/9, 2018 at 10:22 Comment(0)
E
0

In my case I solved the problem editing [tomcat]/Catalina/localhost/[mywebapp_name].xml instead of META-INF/context.xml.

Endpaper answered 1/7, 2013 at 15:11 Comment(0)
C
0

I had this problem on a Tomcat 6. I had the Oracle jdbc driver .jar in two sites, one in the tomcat6/lib folder and in my C:/develop/lib folder which I was pointing on my catalina.properties file:

common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar,C:/develop/lib/*.jar

One of these .jar must be deleted, the tomcat6/lib one or the common.loader one.

Counteraccusation answered 13/7, 2022 at 11:4 Comment(0)
B
-1

If you're using an embedded driver, the connectString is just

jdbc:derby:databaseName 

(whith options like;create=true;user=xxx etc).

If you're using client driver, the connect string can be left as is, but if changing the driver gives no result... excuse the question, but are you 100% sure you have started the Derby Network Server as per the Derby Tutorial?

Brachylogy answered 20/7, 2012 at 14:48 Comment(0)
H
-1

I had a similar problem using Tomcat against Oracle. I DID have the context.xml in the META-INF directory, on the disc. This file was not showing in the eclipse project though. A simple hit on the F5 refresh and the context.xml file appeared and eclipse published it. Everything worked past that. Hope this helps someone.

Try hitting F5 in eclipse

Hanseatic answered 9/6, 2014 at 16:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.