I am trying to inject DataSource into Servlet. Finally I've annotated datasource field with @Resource and some DBCP's BasicDataSource was injected there. But it has no configuration. No db url, no driver class, nothing. Naturally I got NullPointerException when trying to getConnection()
. What am I doing wrong?
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<servlet>
<servlet-name>testServlet</servlet-name>
<servlet-class>ua.test.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>testServlet</servlet-name>
<url-pattern>/serve</url-pattern>
</servlet-mapping>
<resource-ref>
<res-ref-name>jdbc/MyDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<injection-target>
<injection-target-class>ua.test.TestServlet</injection-target-class>
<injection-target-name>dataSource</injection-target-name>
</injection-target>
</resource-ref>
</web-app>
context.xml
<?xml version='1.0' encoding='utf-8'?>
<Context>
<Resource name="jdbc/MyDB" auth="Container" type="javax.sql.DataSource"
maxActive="10" maxIdle="30" maxWait="10000"
username="tomcat" password="tomcat" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/test"/>
</Context>
Obviously no one gave a sh*t about my sorrow. So I will answer myself.
Tomcat has it's own(probably modified) copy of Apache Commons DBCP under package org.apache.tomcat.jdbc
, but also for some stupid reason includes original DBCP under org.apache.commons.dbcp
package. What happens when I try to inject Datasource with @Resource
annotation is Tomcat instanting Datasource from original package and injecting this instance to my field. To make Tomcat to use his own copy of DBCP I had to modify my context.xml
as follows:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/MyDB"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
auth="Container" type="javax.sql.DataSource"
maxActive="10" maxIdle="30" maxWait="10000"
username="tomcat" password="tomcat"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/test"/>
</Context>
Basicaly I just added this line:
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
Thanks to everyone who knew the reason but ignored this question for so long time :-)