3

I'm currently attempting to read a MS SQL Server database table using Tomcat/JNDI. I can read from the table without issue if I manually hardcode the datasource into my Java source, but when I attempt to load the datasource using JNDI, I get a ClassNotFoundException:

java.lang.ClassNotFoundException: com.microsoft.jdbc.sqlserver.SQLServerConnectionPoolDataSource
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1714)
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
org.apache.tomcat.dbcp.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1420)
org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1371)
org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
TestServlet.doGet(TestServlet.java:53)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

I don't expect to see this since I have Microsoft's JDBC driver (sqljdbc4.jar) stored in Tomcat's lib directory (not the app's WEB-INF/lib) and since it works fine when I hardcode the DataSource into my Java source code. Does anyone have any ideas why this is happening or know of anything else that has to be specified to get Tomcat to add the lib directory to the classpath when using JNDI resources?

context.xml:

<Context>

<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>

<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->

<!-- Uncomment this to enable Comet connection tacking (provides events
     on session expiration as well as webapp lifecycle) -->
<!--
<Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
-->

<Resource name="jdbc/dspr" auth="Container" type="javax.sql.DataSource"
    username="<USERNAME OMITTED>"
    password="<PASSWORD OMITTED>"
    driverClassName="com.microsoft.jdbc.sqlserver.SQLServerConnectionPoolDataSource"
    url="<URL OMITTED>"
    validationQuery="select 1"
    />
</Context>

TestServlet.java (doPost() code):

PrintWriter out = response.getWriter();
    try {
        // Servlet fails with a ClassNotFoundException when this block is
        //used rather than the block below
        InitialContext initContext = new InitialContext();
        Context envContext = (Context) initContext.lookup("java:/comp/env");
        DataSource ds = (DataSource) envContext.lookup("jdbc/dspr");

        // =========
        // Servlet works when this is uncommented and the above block is commented out
        //SQLServerConnectionPoolDataSource ds = new SQLServerConnectionPoolDataSource();
        //ds.setURL("<URL OMITTED>");
        //ds.setUser("<DATABASE USER OMITTED>");
        //ds.setPassword("<DATABASE PASSWORD OMITTED>");
        // =========

        Connection c = ds.getConnection();
        Statement s = c.createStatement();
        boolean good = s.execute("select * from DS.test_table1");
        System.out.println("** QUERY GOOD? " + good);
        ResultSet rs = s.getResultSet();
        while (rs.next()) {
            String col = rs.getString("col1");
            String val = rs.getString("val1");
            System.out.println(col + " | " + val);
        }
        c.close();
    } catch (NamingException e) {
        throw new ServletException(e);
    } catch (SQLException e) {
        throw new ServletException(e);
    }
    out.write("hello");
    out.close();
upcrob
  • 165
  • 11
  • Try the solution I provide in this topic http://stackoverflow.com/questions/8253958/classnotfoundexception-when-using-custom-sslsocketfactory/31690328#31690328 – Frank Wu Jul 29 '15 at 02:43

2 Answers2

0

Tomcat includes Apache DBCP and Apache Pool, so you can only need provide the driver class name.

<Resource name="jdbc/dspr" auth="Container" type="javax.sql.DataSource"
      maxActive="100" maxIdle="30" maxWait="10000"
      username="<USERNAME OMITTED>"
      password="<PASSWORD OMITTED>"
      driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
      url="<URL OMITTED>"  />

See an example in Configure Tomcat 6 DataSource using Sql Server 2005. How about the following? Instead of looking for the resource, you could inject it into the servlet. See Connect to Datasource without resource-ref in web.xml

Community
  • 1
  • 1
Paul Vargas
  • 41,222
  • 15
  • 102
  • 148
  • I had actually tried that as well. I just get a ClassNotFoundException for `com.microsoft.sqlserver.jdbc.SQLServerDriver` instead. – upcrob Aug 16 '13 at 17:21
0

As it turns out, I was using com.microsoft.jdbc.sqlserver.SQLServerConnectionPoolDataSource as the driver class name. It is, in fact, com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource. Aka - PEBCAK.

upcrob
  • 165
  • 11