Mysql – Java class issue on Debian 6: java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool

databasefedorajavaMySQLtomcat

I'm having trouble running a script which should rebuild the database for a web service (the Fedora Commons digital repository) which normally runs inside Tomcat 6 (stock Debian version). I'm running it on Debian 6, and though Tomcat starts okay, the rebuild script which I must invoke before running Tomcat is hitting the following problem:

ERROR 2010-10-11 13:26:38.836 [main] (Server) Fatal error while starting server
java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool
 at org.apache.commons.dbcp.BasicDataSource.createConnectionPool(BasicDataSource.java:1492) [na:Nightly-201002202152]
 at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1374) [na:Nightly-201002202152]
 at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044) [na:Nightly-201002202152]
 at org.fcrepo.server.storage.ConnectionPool.getConnection(ConnectionPool.java:283) [fcrepo-server-3.4.jar:na]
 at org.fcrepo.server.utilities.SQLUtilityImpl.i_createNonExistingTables(SQLUtilityImpl.java:281) [fcrepo-server-3.4.jar:na]
 at org.fcrepo.server.utilities.SQLUtility.createNonExistingTables(SQLUtility.java:146) [fcrepo-server-3.4.jar:na]
 at org.fcrepo.server.utilities.rebuild.RebuildDOManager.postInitModule(RebuildDOManager.java:130) [fcrepo-server-3.4.jar:na]
 at org.fcrepo.server.Server.<init>(Server.java:636) [fcrepo-server-3.4.jar:na]
 at org.fcrepo.server.utilities.rebuild.RebuildServer.<init>(RebuildServer.java:43) [fcrepo-server-3.4.jar:na]
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [na:1.6.0_21]
 at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) [na:1.6.0_21]
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) [na:1.6.0_21]
 at java.lang.reflect.Constructor.newInstance(Constructor.java:513) [na:1.6.0_21]
 at org.fcrepo.server.utilities.rebuild.RebuildServer.getRebuildInstance(RebuildServer.java:120) [fcrepo-server-3.4.jar:na]
 at org.fcrepo.server.utilities.rebuild.Rebuild.getServer(Rebuild.java:173) [fcrepo-server-3.4.jar:na]
 at org.fcrepo.server.utilities.rebuild.SQLRebuilder.start(SQLRebuilder.java:111) [fcrepo-server-3.4.jar:na]
 at org.fcrepo.server.utilities.rebuild.Rebuild.<init>(Rebuild.java:106) [fcrepo-server-3.4.jar:na]
 at org.fcrepo.server.utilities.rebuild.Rebuild.main(Rebuild.java:394) [fcrepo-server-3.4.jar:na]
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [na:1.6.0_21]
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [na:1.6.0_21]
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [na:1.6.0_21]
 at java.lang.reflect.Method.invoke(Method.java:597) [na:1.6.0_21]
 at org.fcrepo.server.utilities.rebuild.cli.CLILoader.main(CLILoader.java:77) [fcrepo-server-3.4-cli-loader-main.jar:na]

I don't think Tomcat is managing to connect to MySQL properly.

I'm executing the script as the tomcat6 user. I thought this might be an issue with commons-pool.jar not being in my CLASSPATH, but I've added just about every possible class path directory to the user's environment variables:

$ echo $CLASSPATH
/usr/lib/jvm/java-6-sun/lib/dt.jar:/usr/share/tomcat6/lib:/usr/lib/jvm/java-6-sun/lib/tools.jar:/usr/local/fedora/client/lib:/usr/share/java:/usr/share/tomcat6/bin/bootstrap.jar:/usr/share/tomcat6/lib:/var/lib/tomcat6/common/classes:/var/lib/tomcat6/common/lib:/var/lib/tomcat6/lib:/usr/share/java:/usr/local/fedora/server/bin:/usr/local/fedora/client/lib:/usr/local/fedora/server/bin/fcrepo-server-3.4-cli-loader-main.jar:/var/lib/tomcat6/webapps/fedora/WEB-INF/lib:/var/lib/tomcat6/webapps/fedora/WEB-INF/classes

Commons-pool.jar is located at the following paths:

/usr/share/java/commons-pool.jar
/usr/share/tomcat6/lib/commons-pool.jar

mysql-connector-java should also be in the CLASSPATH. I can't quite figure out what's going wrong. The script sets up the following environment:

# ps aux | grep java
tomcat6   3177 32.0  3.1 533992 64608 pts/1    Sl+  13:32   0:01 /usr/lib/jvm/java-6-sun/bin/java -server -Xmn64m -Xms256m -Xmx256m -Djava.endorsed.dirs=/var/lib/tomcat6/common/endorsed:/var/lib/tomcat6/common/lib -Djavax.net.ssl.trustStore=/usr/local/fedora/server/truststore -Djavax.net.ssl.trustStorePassword=tomcat -Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl -Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl -Dcom.sun.xacml.PolicySchema=/usr/local/fedora/server/xsd/cs-xacml-schema-policy-01.xsd -Dfedora.home=/usr/local/fedora -Dfedora.web.inf.lib=/var/lib/tomcat6/webapps/fedora/WEB-INF/lib org.fcrepo.server.utilities.rebuild.cli.CLILoader org.fcrepo.server.utilities.rebuild.Rebuild

I would be grateful for any assistance.

Best Answer

java.lang.NoClassDefFoundError means the runtime version of the class in the classpath is not the same as that at compile time.

Note: it's not a ClassNotFound

Your problem is in fact multiple versions of the class being found.

Update

I should have pointed out before Tomcat does not use the system CLASSPATH. The values set there should get ignored.

http://www.chemaxon.com/jchem/doc/admin/tomcat.html shows anything you put into $CATALINA_HOME/lib automatically gets into the server classpath at startup time.

The jars gets picked up by the shared.loader or common.loader property of /conf/catalina.properties

Mine reads

common.loader=${catalina.home}/lib,${catalina.home}/lib/*.jar

So I think the problem is that you might also have a copy of this class/jar in some other locations from which Tomcat builds it's classpath.

That is anything in WEB-INF/classes and in JARs under WEB-INF/lib in your deployment are in the CLASSPATH, along with JARs that are installed in lib for Tomcat 6.

Also see http://www.jarfinder.com/index.php/java/info/org.apache.commons.pool.impl.GenericObjectPool for a list of other jars containing the GenericObjectPool class, and remove ones other than commons-pool.jar

Update 2

Yes, you can remove the containing folder, and the jars will no longer be in the classpath.

However, I see you have these folders in classpath, do they contain any versions of these jars? Tomcat 6 puts everything in tomcat6/lib, there is no tomcat6/common/lib which is a relic from earlier Tomcat versions. I wonder if these have incorrectly been renamed from an earlier classpath entry ?

/var/lib/tomcat6/common/classes:
/var/lib/tomcat6/common/lib: