Search code examples
javajakarta-eetomcatservletsclassloader

Conflicting JARs: shouldn't WEB-INF/lib take precedence over all others places?


My deployment environment is very messed up: jar files are scattered all over the system, and I have no control on it. For example my webapp uses a recent version of Javamail API, but is seems that in $JAVA_HOME/jre/lib/ext there are multiple copies of the same library (obviously all older and different versions). The same applies for database vendors' drivers, not to mention $CATALINA_HOME/lib. I can't clean up anything, but obviously I need to ensure that my app gets the minimum required version of its dependencies, so I put all the required JARs in WEB-INF/lib. According to Servlet spec and Tomcat docs:

When a request to load a class from the web application's WebappX class loader is processed, this class loader will look in the local repositories first, instead of delegating before looking

so it should solve my problem. But then the very same doc says:

Therefore, from the perspective of a web application, class or resource loading looks in the following repositories, in this order:

  1. Bootstrap classes of your JVM
  2. System class loader classes (described above)
  3. /WEB-INF/classes of your web application
  4. /WEB-INF/lib/*.jar of your web application
  5. Common class loader classes (described above)

And actually the classes in /WEB-INF/lib are loaded after system ones. Is this indeed expected behavior? Don't you find that the Tomcat docs is contradictory? Do you know any servlet container which guarantees that I can get the correct dependencies? How can I solve this problem?


Solution

  • If the ext-folder is contaminated you are basically out of luck.

    The only thing you can do, is to repackage all the code you need - including jars - in a separate package hierarchy and package with your application. This would mean that com.foo.Bar would become org.raffaele.com.foo.bar or similar. Then use only these new names.

    Watch out for reflection and strings with class names, but it can be done.

    I do not know if there is a tool that can fully automate this process.