1
votes

I have an Java 6 application installed on Tomcat 6. The application jar file and dependency jar files live in my webapps/myapp/WEB-INF/lib directory, while my logback config file lives in webapps/myapp/WEB-INF/classes.

The app is the only app that runs in a tomcat instance, and we run around a hundred instances at a time. The server admin team decided that the app and dependency libs are redundant and moved them to tomcat/lib.

First they moved just the myapp.jar to tomcat/lib. This resulted in a exception:

java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

This is a bit weird as, if anything, i would expect it to fail trying to load my app. Instead it appears that loading the app from a jar in tomcat/lib has changed the path of the classloader. I thought that the web app directory, and of course the WEB-INF/web.xml, would "anchor" the classloader to the application directory. This doesn't seem to be the case.

When that didn't work, the admin team moved all the rest of the dependency libs to the tomcat/lib directory. Now the app starts up, finds it's configuration properties files, etc., but does not locate the logback.xml file (in WEB-INF/classes/logback.xml). Again, this suggests that something has significantly changed in the class loader environment.

The most important consequence is that if I place a new dependency in my WEB-INF/lib directory it is no longer seen by my application. And of course it would be nice to see my logging config file again without having to move it to tomcat/lib as well.

Any ideas on what is going on with my configuration?

2

2 Answers

2
votes

If your server runs on Linux, there is an alternative setup that could prevent those classloader issues and (maybe) make your server admin happy. You could put the common jars in some directory (not under tomcat/lib) and then create symlinks to these jars under each webapp's WEB-INF/lib directory.

I have used this setup for years and it has worked well for me. You can create a shell script that scans the common jars directory and creates symlinks for each webapp, and you can setup this script to run automatically when Tomcat starts (e.g. by calling it from Tomcat's startup script).

0
votes

I just solved a similar problem with my own project. For starters, make sure the logback.xml file is actually in the resulting .war file, and where your application is expecting it to be. If you are on a Mac then check out Jarzilla for inspecting the contents of WARs and JARs without having to extract them. This turned out to be the problem in my case.

Also, if you are having dependency issues then you may want to look into a project build manager like Apache Maven or Gradle or even Apache Ant.

Hope this helps!