2

I have a simple servlet that uses Tomcat-DBCP to fetch connections.

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
...
  Connection conn = null;
  try {
    conn = createConnection();
....
}
public Connection createConnection() throws SQLException {
        Connection conn = null;
        DataSource datasource = new DataSource();
        PoolProperties p = new PoolProperties();
        p.setUrl("jdbc:oracle:thin:@localhost:1521:XE");
        p.setDriverClassName("oracle.jdbc.OracleDriver");
        p.setUsername("SYSTEM");
        p.setPassword("password");
        datasource.setPoolProperties(p);
        try {
             conn = datasource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

It needs ojdbc6.jar in tomcat's /lib folder and not in WEB-INF/lib.

  1. Why doesn't the web-apps own lib folder work?
  2. Based on a answer here, binding driver code with the common class loader causes memory leaks. If true, what is the workaround?
Community
  • 1
  • 1
John Eipe
  • 10,922
  • 24
  • 72
  • 114
  • Look here: http://stackoverflow.com/questions/21015991/jdbc-driver-has-been-forcibly-unregistered-by-tomcat-6/21016037#21016037 – Michael-O Jan 10 '14 at 19:42
  • tomcat's /lib doesn't work for you? – J.P. Armstrong Jan 10 '14 at 19:45
  • yes it does. But why isn't web-inf/lib not working – John Eipe Jan 10 '14 at 20:24
  • @Michael-O i'm not using context-look up. Just normal DataSource object creation that happens only at run-time when my servlet runs. So shouldn't it be visible to the classloader? – John Eipe Jan 10 '14 at 20:29
  • Tomcat uses, by default, a two-level Classloader system. There's the system-wide Classloader, and then there's a Classloader for each WAR. Classes inside a WAR can use classes found by the system Classloader, but the opposite is *not* the case. Tomcat-DBCP is loaded by the system Classloader, so it cannot use a JDBC driver that is loaded by a WAR's Classloader. – dcsohl Jan 10 '14 at 21:04
  • The answers to your questions haven been given - all correct. However, the bigger issue here is that you shouldn't open data sources and connections in your code. Period. Do yourself a favor and let the container manage data sources, connections and their pool. The [Tomcat docs](http://tomcat.apache.org/tomcat-7.0-doc/jndi-datasource-examples-howto.html#Oracle_8i,_9i_&_10g) show you how. – Marcel Stör Jan 10 '14 at 23:15
  • @dcsohl I think it's common classloader and not system classloader. – John Eipe Jan 12 '14 at 16:33
  • You're right - I was using the wrong terminology, thinking of Tomcat as "the system"... but it's a Tomcat classloader and not the system/JRE classloader. – dcsohl Jan 13 '14 at 14:31

1 Answers1

2

The answer to your first question is the very link you reference in your second question. That's why you should put JDBC drivers in /lib. Normally people advise against using /lib but JDBC drivers are a big exception.

For your second question, the workaround is to put it in Tomcat's shared /lib folder. That's it. That is the fix.

dcsohl
  • 7,186
  • 1
  • 26
  • 44
  • So you mean, though using shared /lib increases chances of memory leaks in this case that's the only workaround? – John Eipe Jan 10 '14 at 20:26
  • Your link - the other SO question you cited - says, "putting JDBC drivers into Tomcat's lib folder will help prevent memory leaks when you redeploy your web app without restarting Tomcat, e.g. if you just put a new WAR file into Tomcat's webapps folder." So it's pretty much the opposite of what you're saying. Using shared `/lib` will **decrease** chances of memory leaks. – dcsohl Jan 10 '14 at 21:00
  • The downside of `/lib` is that all `WAR`s in the system will have to use the same version of the JDBC driver. That's one of the big reasons usually cited against using `/lib`, but for JDBC the benefits outweigh the costs. – dcsohl Jan 10 '14 at 21:02
  • you are right. I read it wrong. I should have slept instead of continuing. ;-) – John Eipe Jan 12 '14 at 13:20