I am trying to create simple web-app. And stuck on datasource injection. There seems to be several problems. So I will start from my confusion. As I understand there's 2( at least) ways to inject the DataSource into Servlet:
web.xml sample
<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>
@Resource sample
public class TestServlet extends HttpServlet{
@Resource
private DataSource dataSource;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
My confusion : web.xml
doesn't work in Tomcat 7 on my simple project. In my opinion, web.xml
option should work since there were no annotations before Java 5. Please explain.
Update:
Datasource configuration
<Resource name="jdbc/MyDB"
type="javax.sql.DataSource"
auth="Container"
username="SA"
password=""
driverClassName="org.hsqldb.jdbcDriver"
url="jdbc:hsqldb:file:~/database/my_db"
/>
Try taking out the injection-target
entry in web.xml
and using the name
attribute on the @Resource
annotation:
public class TestServlet extends HttpServlet {
@Resource(name = "jdbc/MyDB")
private DataSource dataSource;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
That worked in my local testing with Tomcat 7.0.50. If you're looking for the annotation-less way of doing it, I haven't gotten that to work, even though it should given their changelog1.
EDIT
I still haven't found a solution, but I was curious why this doesn't work so I took a look at the injection-target
code. I found that it loads the context.xml
entry first, and does pick up the settings from web.xml
, but chooses not to override the configuration it found in context.xml
because it already sees a jdbc/MyDB
entry. I'm not sure how to get the injection-target
settings into context.xml
or the DB settings like driverClassName
into web.xml
.
As far as I know, tomcat is a nice servlet container, but it is not a full Java EE container. From The BalusC Code: How to install CDI in Tomcat?, I think that out of the box tomcat is not able to do any dependency injection. Tomcat alone works perfectly associated with Spring, because it is lightweight.
If you do not want to use Spring, the link I wrote above should give you some ways to do CDI with tomcat (TomEE instead of tomcat, Weld or OpenWebBeans).
EDIT:
Apparently, recent versions of tomcat 7 should accept DI - see below the link in comment from davidfmatheson.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With