Tomcat can not access the jar library referenced by my library in WEB-INF / lib


I am developing web application using Tomcat 7. It uses my MyLib.jar that is placed under webapps\MyApplication\WEB-INF\lib. This library is successfully loaded by Tomcat. The problem is with libraries that are needed by MyLib.jar (let's say A.jar and B.jar).

While creating MyLib.jar I added MANIFEST with Class-path: otherLibs\A.jar otherLibs\B.jar (which are placed under webapps\MyApplication\WEB-INF\lib\otherLibs).

What is interesting, MyLib.jar can be run from command line without any problems.

It all works for me when I copy A.jar and B.jar to \lib directory. I just don't want to put them there to keep Tomcat installation clean.

Maybe I need to specify extra class path for MyApplication? Maybe globally for Tomcat? How then? Please provide any suggestions.

EDIT: Strange. I run some additional tests. I changed classpath of MyLib.jar to "A.jar B.jar" (without otherLibs directory), put A.jar and B.jar next to MyLib.jar and now it works fine. It works for me, but could you tell me why it is not working with "otherLibs" directory?

Here is whats going on with your application (trying to answer could you tell me why it is not working with "otherLibs" directory?):

  1. When you run your jar from the command line, JVM uses the standard class-loading mechanism, i.e. Bootstrap classloader -> Extension classloader -> Application classloader. This application classloader loads the classes from CLASSPATH environment variable, -classpath or -cp command line option, Class-Path attribute of Manifest file inside JAR. This is the reason why it works from command line. More here.

  2. The Server (like tomcat) classloading mechanism is different from the standalone application. They use custom class loading. This is the reason that only putting your all jars in WEB-INF/lib simply works as the custom class loader is meant to load jars from WEB-INF/lib folder in your application. As is evident, the custom classloader does not regard the entries in Manifest file inside JAR and hence ignores all the jars not directly in WEB-INF/lib. It works when you copy the jars in WEB-INF/lib as custom class loader is not able to find them.