What follows is lessons learned migrating to the potentially magnificent Maven2 for dependency management.
Put <scope>provided</scope> on Tomcat shared resources in your pom.xml
If you deploy jars as a shared resource on Tomcat (i.e. put the jars in common/lib) then be sure to add the <scope>provided</scope> to those dependencies in your project’s pom.xml. Otherwise, you’ll get absolutely daft class-cast errors on shared resources like:
2007-10-21 12:42:19,425 ERROR 0-SNAPSHOT] - Servlet /myExample2-1.0-SNAPSHOT threw load() exception
java.lang.ClassCastException: org.apache.jackrabbit.core.jndi.BindableRepository cannot be cast to org.apache.jackrabbit.core.jndi.BindableRepository
Hahahahahahaha I think I want to kill myself. The problem is that Tomcat’s shared libraries are loaded by a different classloader than your web-app’s shared libraries (which is nice in a way, because it means you can use different versions of log4j or whatever).
So the lesson here is: Anything you want created by Tomcat and loaded by name (e.g. “jcr/repository”), be sure to exclude from your WEB-INF/lib when you deploy.
You can load the same shared resource by name for all apps
Deploying a Maven2-enabled app using Codehaus Mojo is a breeze… unless you want to deploy a context with it. And a context is the only way to load up named shared resources like a Jackrabbit repository. The solution?
$TOMCAT_HOME/conf/Catalina/$HOSTNAME/context.xml.shared
The contents are loaded for all contexts. Brilliant.
Class blahblah violates loader constraints
Oh no. This was awful. For me it was:
2007-10-21 13:16:26,331 ERROR 0-SNAPSHOT] - Exception starting filter DataServlet
java.lang.LinkageError: Class org/slf4j/ILoggerFactory violates loader constraints
I needed to scour the dependencies that Maven was loading into my webapp automatically and explicitly label them as provided.
Why put libs in the shared Tomcat lib dir to start with though? That’s just asking for trouble 🙂
LikeLike