Where to put c3p0 dependency in Tomcat Container
Asked Answered
A

1

1

I was under the impression that the libraries for both the database driver (postgres-x.x.jar'in my case) and the connection pooler (c3p0) had to reside in the container's lib (e.g. for Tomcat7, $CATALINA_HOME/lib).

However, the official C3p0 documentation doesn't provide any information with regards to put the connection pool's jar in the container vs having it in the application's war:

Place the files lib/c3p0-0.9.5.2.jar and lib/mchange-commons-java-0.2.11.jar somewhere in your CLASSPATH (or any other place where your application's classloader will find it). That's it!

A current issue in a new tomcat installation (java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector, when I have the mchange-commons-java dependency in the application's WAR and the c3p0 dependency in $CATALINA_HOME/lib) made me revisit this, but I can't find any authoritative information regarding where to put these libraries.

Usual application configuration
In my case the c3p0 configuration is made via spring bean within the application's classpath:

<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        scope="singleton" destroy-method="close">
        <property name="driverClass">
            <value>org.postgresql.Driver</value>
        </property>
        <property name="jdbcUrl">
            <value>${jdbc.url}</value>
        </property>
        <property name="user">
            <value>${jdbc.user}</value>
        </property>
        <property name="password">
            <value>${jdbc.pw}</value>
        </property>
        ...
<bean> 

If I have multiple applications in the same Tomcat container, each will have one c3p0 bean like this contained in its war.

Memory Leaks?

The assumption for having the postgres.jar and c3p0.jar in the container's lib/ and not in the war was that the latter would cause memory leaks.

Leak in Postgres Driver

This user states that JDBC drivers register themselves in the JVM-wide singleton DriverManager which is shared by all web apps. If you have the same (as in class name) JDBC driver register twice from two different web apps, this might cause your problem. This is even more problematic if your web apps use different versions of the same JDBC driver.

Leak in c3p0 We moved c3p0 to $CATALINA_HOME/lib after this comment on Stackoverflow (we had a similar warning when undeploying an application).

Should they reside in Tomcat or the application's lib/ ?

Accede answered 10/8, 2017 at 18:29 Comment(0)
M
0

Whether or not you need to put a jar in Tomcat's lib directory depends on whether Tomcat needs to know about it or not. And that depends on how you are configuring things.

As a general rule, if you are mentioning a class in a Tomcat config file, then that class (and those that it depends on) must be in Tomcat's lib directory.

For example, if you configure your DataSource in Tomcat's config files, then you need to make your driver class available to Tomcat. If instead you configure your DataSource within your application's code then you do not.

You do not specify how you are configuring C3P0, so we cannot tell you where the jar needs to be. Of course, if Tomcat needs it and it is not there, then you should expect to see an exception logged and things won't work properly.

Maidservant answered 10/8, 2017 at 18:38 Comment(2)
The c3p0 properties file is within the application's classpath (and speaking by heart I think its in that file that the driver class is defined). Even if I have multiple applications in the same container, I will have one c3p0 within each war. However, the assumption for putting the postgres and c3p0 jars in the container was that memory leaks would crawl if they were placed on each application's warAccede
I added more contextual information to the question above.Accede

© 2022 - 2024 — McMap. All rights reserved.