我正在使用Tomcat 7.0.12并且每当我通过名为“ROOT”的webapp中的.jsp页面访问连接到postgresql数据库的JNDI数据源时都会收到此错误:
SEVERE: Servlet.service() for servlet [jsp] in context with path [] threw exception
[java.lang.RuntimeException: Cannot create JDBC driver of class '' for connect URL 'null'] with root cause
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)
at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1371)
at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
postgresql JDBC驱动程序位于我的CATALINA / lib文件夹中。
这是我的META-INF / context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/webdbro" auth="Container" type="javax.sql.DataSource"
driverClassName="org.postgresql.Driver" url="jdbc:postgresql://127.0.0.1:5432/webdb"
username="webdbro" password="pass" maxWait="-1" removeAbandoned="true" removeAbandonedTimeout="30"/>
<Resource name="jdbc/webdbrw" auth="Container" type="javax.sql.DataSource"
driverClassName="org.postgresql.Driver" url="jdbc:postgresql://127.0.0.1:5432/webdb"
username="webdbrw" password="pass" maxWait="-1" removeAbandoned="true" removeAbandonedTimeout="30"/>
<Resource name="jdbc/shadowdbro" auth="Container" type="javax.sql.DataSource"
driverClassName="org.postgresql.Driver" url="jdbc:postgresql://127.0.0.1:5432/shadowdb"
username="shadowdbro" password="pass" maxWait="-1" removeAbandoned="true" removeAbandonedTimeout="30"/>
</Context>
这是我的WEB-INF / web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>ROOT</display-name>
<resource-ref>
<description>Read only webdb connector.</description>
<res-ref-name>jdbc/webdbro</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<resource-ref>
<description>Read write webdb connector.</description>
<res-ref-name>jdbc/webdbrw</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<resource-ref>
<description>Read only shadow db connector.</description>
<res-ref-name>jdbc/shadowdbro</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
奇怪的是我使用完全相同的配置(web.xml和context.xml)在同一个Tomcat服务器上运行了2个其他webapp,因此他们可以使用JNDI方法连接到数据库和这些webapps的两个工作得很好 - 我可以在这些应用程序中查询和更新数据库,没有任何问题或例外。 TIA ...
答案 0 :(得分:17)
为了让所有3个webapps正确使用相同的数据源,我必须将所有<Resource>
条目从META-INF / context.xml文件夹移动到服务器的$ CATALINA_BASE / conf / context.xml中夹。不是一个很好的解决方案,但它确实有效。
答案 1 :(得分:3)
我遇到了同样的问题,结果是我对context.xml上的<Resource>
名称声明与web.xml上<resource-ref>
名称上定义的名称声明不匹配。
答案 2 :(得分:2)
如上所述,一种解决方案是将条目移动到$ CATALINA_BASE / conf / context.xml
此处描述了另一种方法: http://blogs.agilefaqs.com/2009/11/23/cannot-create-jdbc-driver-of-class-for-connect-url-null/
特别是,“将Context.xml文件复制到tomcat / conf / Catalina / localhost文件夹并将其重命名为<web_app_name>.xml
”
根本原因可能是由于文件权限问题:“运行tomcat的用户没有写入这些文件夹的权限。所以我们将tomcat和/ etc / tomcat文件夹的组所有权更改为tomcat用户所属的同一组,并且神奇地一切都像以前一样开始工作。“
这个解决方案对我来说似乎“更清洁”,因为您可以将整个Web应用程序(包括数据库连接属性)包含在.war文件中。