• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 21627
  • Last Modified:

Tomcat - Connection error from DataSource using JNDI

Hi, I'm trying to connect to an Oracle 8i database using JNDI lookup from Tomcat 4.1.30 and get an error I can't figure out.

The error message reads: org.apache.commons.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
This error seems to be when I try to get a connection from the DataSource object:
Connection conn = datasource.getConnection();

In attempts to figure this out, I created a test servlet that first connects to the database using the hard-coded driver and url, then JNDI.

The servlet doGet looks like this:
                  protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            
            PrintWriter out = response.getWriter();
            String sDriver = "oracle.jdbc.driver.OracleDriver";
            String sURL = "jdbc:oracle:thin:@somecompany.com:1521:db1";
            try {
                  out.println("Attempting Oracle connection<br>");
                  Class.forName(sDriver).newInstance();
                  Connection conn = DriverManager.getConnection(sURL, "scott", "tiger");
                  conn.close();
                  out.println("Connected to Oracle okay<br>");
            
            } catch (InstantiationException e) {
                  out.println(e.getClass()+": "+e.getMessage()+"<br>");
            } catch (IllegalAccessException e) {
                  out.println(e.getClass()+": "+e.getMessage()+"<br>");
            } catch (ClassNotFoundException e) {
                  out.println(e.getClass()+": "+e.getMessage()+"<br>");
            } catch (SQLException e) {
                  out.println(e.getClass()+": "+e.getMessage()+"<br>");
            }
            
            InitialContext ctx;
            try {
                  out.println("Attempting JNDI connection<br>");
                  ctx = new InitialContext();
                  Context envctx = (Context) ctx.lookup("java:comp/env");
                  DataSource datasource = (DataSource) envctx.lookup("jdbc/operations");
                  Connection conn = datasource.getConnection();
                  conn.close();
                  out.println("Connected to JNDI okay<br>");
            }
            catch (NamingException e) {
                  out.println(e.getClass()+": "+e.getMessage()+"<br>");
            } catch (SQLException e) {
                  out.println(e.getClass()+": "+e.getMessage()+"<br>");
            }
            
      }

The output looks like this:
Attempting Oracle connection
Connected to Oracle okay
Attempting JNDI connection
class org.apache.commons.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'

My server.xml looks like:
...
<GlobalNamingResources>
    <Environment name="simpleValue" override="true" type="java.lang.Integer" value="30"/>
     <Resource auth="Container" name="jdbc/operations" scope="Shareable" type="javax.sql.DataSource"/>
     <ResourceParams name="jdbc/operations">
        <parameter>
            <name>factory</name>
            <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
        </parameter>
        <parameter>
            <name>driverClassName</name>
            <value>oracle.jdbc.driver.OracleDriver</value>
        </parameter>
        <parameter>
            <name>url</name>
            <value>jdbc:oracle:thin:@somecompany.com:1521:db1</value>
        </parameter>
        <parameter>
            <name>username</name>
            <value>scott</value>
        </parameter>
        <parameter>
            <name>password</name>
            <value>tiger</value>
        </parameter>
        <parameter>
            <name>maxActive</name>
            <value>20</value>
        </parameter>
        <parameter>
            <name>maxIdle</name>
            <value>10</value>
        </parameter>
        <parameter>
            <name>maxWait</name>
            <value>5000</value>
        </parameter>
      </ResourceParams>

  </GlobalNamingResources>
...

My web.xml looks like:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
     PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
      <!-- define global vars -->
      
      
      <servlet>
     <servlet-name>TestServlet</servlet-name>
     <servlet-class>testJNDI.TestJNDI</servlet-class>
    </servlet>
   
      <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/servlet/TestJNDI</url-pattern>
    </servlet-mapping>
      
      <session-config>
            <session-timeout>120<!-- in minutes --></session-timeout>
      </session-config>
      <resource-ref>
            <description>Oracle Datasource</description>
             <res-ref-name>jdbc/operations</res-ref-name>
            <res-type>javax.sql.DataSource</res-type>
            <res-auth>Container</res-auth>
</resource-ref>

      
</web-app>


Help!

Thanks in advance.
0
topher1120
Asked:
topher1120
1 Solution
 
vzilkaCommented:
Can you remove the factory parameter and tell us the result?
0
 
topher1120Author Commented:
Removed the parameter with the same result.  I don't know if this matters much, but its running on Win2k w/ JDK 1.4.
0
 
vzilkaCommented:
DId you put the classes12.jar in your web-inf/lib directory, or the TOMCAT\shared\lib directory?
0
Get your Conversational Ransomware Defense e‑book

This e-book gives you an insight into the ransomware threat and reviews the fundamentals of top-notch ransomware preparedness and recovery. To help you protect yourself and your organization. The initial infection may be inevitable, so the best protection is to be fully prepared.

 
topher1120Author Commented:
I have it in TOMCAT_HOME\common\lib.  Tried moving it to TOMCAT_HOME\shared\lib, but to no avail.
0
 
vzilkaCommented:
classes12.zip or classes12.jar?
0
 
topher1120Author Commented:
classes12.jar.  I even removed the javax package in it to see if it would help (saw in another post that may cause some problems.)
0
 
vzilkaCommented:
Double check the url property. Can it really be used to connect to the database?
YOu can write a small servlet that creates a JDBC connection and run it inside Tomcat.
This way we will know if the jdbc driver is in the classpath, and the database is valid.
0
 
topher1120Author Commented:
vzilka,  please see my initial post.  I provided the doGet method of my test servlet and the output it produces.  Although I did change the url, username and password for the post, I have checked that they are both the same.  I even tried copy-paste from the working portion to the jndi setup.  When I initially set this up, I used the Tomcat administration application.  It would really help if they had some way to check connectivity from within Tomcat :).  
0
 
topher1120Author Commented:
I believe I figured this out.  When I had added the datasource information in server.xml, I put it under "GlobalNamingResources".  Because of this and the fact I had nothing in my context that pointed to it, it couldn't find it.  As soon as I put a "ResourceLink" element in my context, the JNDI lookup succeeded.  I'm betting if I had defined the resource in the context, what I had posted would have worked.

0
 
vzilkaCommented:
You are right. Sorry for not picking this up immediately, this is one of the oldest in the book.
0
 
moduloCommented:
Closed, 250 points refunded.

modulo
Community Support Moderator
Experts Exchange
0
 
gk_97Commented:
Ho topher1120

I am experincing
17:01:43,422 [ConnectDB.java] [ConnectDB] [getConnectionPoolForOracle:101] - ERR
OR - failed to get the connection: org.apache.commons.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null', cause: No suitable
driver-

I read your comment about ResourseLink.
I am unsure on where to include that.

Do i need to create a separate tag <Context> in the server.xml and include it in there?

or do i need to create a separate file context.xml and add the tag there?
I am using Tomcat 5.0.28

The resource parameters are in the <GlobalNamingResources> tag - does the context tag need to be around this?

thanks

0

Featured Post

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now