8
votes

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?

1
Why don't you put them under \WEB-INF\lib instead of creating another subfolder?regulus
I just did, changed classpath and it works fine (see EDIT: in my question). Just out of curiosity, why it is not working with subfolder?user464592
You don't need to refer your libs with class-path when they're located under WEB-INF\lib. As I know in the JRE spec, libs are only searched under this folder without checking the class path.regulus
MyLib.jar is added to MyApplication project that is built into .war file. I don't add A.jar and B.jar to this project.user464592

1 Answers

8
votes

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.