4

Does anyone know the place where the order is specified in which classes from jars are loaded in tomcat8?

Here is our scenario: We have two absolutely identical servers (hardware and os). Both are running java 1.7.65 and have a tomcat installed in version 8.0.32. Start and VM parameters are exactly the same, as well as application specific settings (second machine is just a redundant system). The only difference is the ip address and of course the hostname.

After a recent upgrade from Tomcat7 to Tomcat8 (on both systems), the long time ignored messages from slf4j saying "found multiple bindings..." at application startup brought us to another circumstance which caused an error that prevented our application from proper logging - The sorting / ordering of classloading. That´s because one system is loading logback-classic-1.0.13.jar first and on the second system slf4j-log4j12-1.6.6.jar get´s loaded first. We only have a logback.xml and no log4j.xml deployed and so the log messages do not appear in the right files because the loaded StaticLoggerBinder is not the correct one.

Output from system-1

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/backoffice/apache-tomcat-8.0.32/webapps/backoffice/WEB-INF/lib/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/opt/backoffice/apache-tomcat-8.0.32/webapps/backoffice/WEB-INF/lib/slf4j-log4j12-1.6.6.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
16:50:26,740 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
16:50:26,740 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
16:50:26,741 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/opt/backoffice/apache-tomcat-8.0.32/webapps/backoffice/WEB-INF/classes/logback.xml]

Output from system-2

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/backoffice/apache-tomcat-8.0.32/webapps/backoffice/WEB-INF/lib/slf4j-log4j12-1.6.6.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/backoffice/apache-tomcat-8.0.32/webapps/backoffice/WEB-INF/lib/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader).

(Yes, i know how to fix it via maven dependencies and i will surely remove the duplicate / redundant dependencies from my pom... O:-) )

Now my question is, how is it possible that the order is different on two absolutely identical systems?

jubi
  • 485
  • 7
  • 19

1 Answers1

1

Java loads classes in the order they are specified on the classpath.

Tomcat does not resolve classpaths in the same way other Java programs do, e.g. using the CLASSPATH environmental variable, or the -classpath command line flag. Also how Tomcat resolves classpaths can and does change with each major release (this may be why your issue was introduced).

I see much reading on this in your future :) Here is somewhere good to begin: Understanding the Tomcat classpath

Paul MacGuiheen
  • 628
  • 5
  • 17
  • Thanks for your answer. Yes, we already figured out that it has to do something with tomcat because the last changes on our systems have just been the upgrades of the tomcat versions. Anyway, i still cannot imagine how and why the loading machanism can be different between two identical systems running the same software versions... I will start reading :) – jubi Apr 06 '16 at 05:53
  • @Paul, link is broken – Stijn Geukens Jun 03 '23 at 15:31