Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tomcat 7 Datasource injection mechanism

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
  • @Resource

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" 
/> 
like image 580
Aleksandr Kravets Avatar asked Mar 19 '23 10:03

Aleksandr Kravets


2 Answers

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.

like image 115
davidfmatheson Avatar answered Apr 02 '23 10:04

davidfmatheson


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.

like image 34
Serge Ballesta Avatar answered Apr 02 '23 10:04

Serge Ballesta