Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controlling the classpath in a servlet

My servlet application includes a number of library .jars, some of which contain embedded log4j.xml or log4j.properties files. I'd like to ensure that log4j finds my log4j.xml first! I've tried searching for some specification of the priorities of the various classpath elements in a servlet (e.g. does WEB-INF/classes always precede WEB-INF/lib?), or some way to configure or tweak the servlet's classloader so that a given resource directory appears early in the classpath. So far, I've drawn a blank. Any suggestions on ensuring that a servlet .war file loads the correct log4j.xml via the classloader?

like image 441
Ian Dickinson Avatar asked Nov 05 '08 10:11

Ian Dickinson


2 Answers

Tomcat 8.5

Ditto Tomcat 8.0.

See documentation: Class Loader HOW-TO.

Tomcat 8.0

The answer is simple, taken from the Tomcat documentation page, Class Loader HOW-TO. In particular notice the use of the /WEB-INF/ directory/folder.

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

  • Bootstrap classes of your JVM
  • /WEB-INF/classes of your web application
  • /WEB-INF/lib/*.jar of your web application
  • System class loader classes (described above)
  • Common class loader classes (described above)

If the web application class loader is configured with <Loader delegate="true"/> then the order becomes:

  • Bootstrap classes of your JVM
  • System class loader classes (described above)
  • Common class loader classes (described above)
  • /WEB-INF/classes of your web application
  • /WEB-INF/lib/*.jar of your web application

Tomcat 6

Excerpted from Tomcat 6 page, Class Loader HOW-TO.

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

  • Bootstrap classes of your JVM
  • System class loader classes (described above)
  • /WEB-INF/classes of your web application
  • /WEB-INF/lib/*.jar of your web application
  • $CATALINA_HOME/lib
  • $CATALINA_HOME/lib/*.jar
like image 166
Yonatan Maman Avatar answered Oct 04 '22 10:10

Yonatan Maman


As far as I understand the resource selection from the classpath is non-deterministic (from the point of view of the app developer). Even if the same file is loaded consistently the behaviour could change: 1. When you upgrade the version of your current container. 2. If you switch containers.

The simplest solution will be to remove embedded log4j config files from library jars. It is almost never a good idea to embed log4j config's as it leads to the problem you are seeing here...

Are they third party jars or jars you developed?

like image 20
johnstok Avatar answered Oct 04 '22 11:10

johnstok