Ответ 1
Чтобы все 3 веб-приложения использовали один и тот же источник данных, мне пришлось переместить все мои записи <Resource>
из папки META-INF/context.xml в папку $CATALINA_BASE/conf/context.xml сервера. Не отличное решение, но оно работает.
Я использую Tomcat 7.0.12 и получаю эту ошибку всякий раз, когда я пытаюсь получить доступ к источнику данных JNDI, подключающемуся к postgresql db через страницу .jsp в webapp под названием ROOT:
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>
Странно, что у меня есть еще 2 веб-приложения, которые работают на одном сервере Tomcat, используя ту же самую конфигурацию (web.xml и context.xml), чтобы они могли использовать JNDI-метод для подключения к базе данных и ОБОИХ из тех веб-приложений работать отлично - я могу запросить и обновить базу данных без каких-либо проблем или исключений в этих приложениях. ТИА...
Чтобы все 3 веб-приложения использовали один и тот же источник данных, мне пришлось переместить все мои записи <Resource>
из папки META-INF/context.xml в папку $CATALINA_BASE/conf/context.xml сервера. Не отличное решение, но оно работает.
У меня была такая же проблема, и оказалось, что моя декларация имени <Resource>
в context.xml не соответствует той, которая определена в <resource-ref>
name на web.xml.
Как было сказано выше, одним из решений является перемещение записей в $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, и магически все начинало работать, как и раньше".
Это решение кажется мне "более чистым", потому что теперь у вас есть все веб-приложение, включая свойства подключения к базе данных, завернутые в .war файл.