Home > front end >  Does common loader of Tomcat cannot refer jar inside WEB-INF/lib?
Does common loader of Tomcat cannot refer jar inside WEB-INF/lib?

Time:05-02

I have a Tomcat that contains some logback*.jar jars in the tomcat/lib, well when my WEB-INF/lib contain the same jars of logback*.jar it starts up fine, but when I remove the logback*.jar of WEB-INF/lib, and then startup will mention LoggerFactory class not found. So I copy the slf4j-api*.jar into the tomcat/lib it starts up fine again.

I'm curious does common loader cannot refer to jars inside the WEB-INF/lib?

It must place logback*.jar and dependency jar slf4j-api*.jar in the same place?

And why does when WEB-INF/lib contains these jars work fine? It looks like jars inside WEB-INF/lib can replace tomcat/lib, and reverse can't. Am I right?

reference: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

CodePudding user response:

You have the common classloader, which is available to the server and all web applications, and you have a web application's classloader, which is only available to each individual web application. The webapp classloader also has access to the common (sic!) classloader, but not vice versa - so you're right.

Why all of this?

Some resources are provided by the server, thus they need to be available to the server (not just to the web application). Think of database drivers that are provided through JNDI, typically initiated by the server. Logging facilities - especially when they're configured through the server - are another great candidate, like in your case.

It's important that you do not duplicate any classes on the classpath - e.g. if you have a jar in the common classloader (tomcat/lib), do not add it to a webapp's classpath. Otherwise you may end up with seemingly unexplainable ClassCastException, where an object can't be typecasted to its own type or a legitimate supertype (but from a different classloader)

So, if you need some resources on the server's classpath (and passed into your webapp), you'll have to deploy those in the common classpath, tomcat/lib. If you only need them within the webapp: Keep them as local as possible (this would allow other webapps on the same server to bring their own version - literally the same library but in a different version - without any conflict). In the ancient past, the common classloader has been utilized to save some memory (by not localizing resources that every webapp uses), but given the price of RAM vs the typical size of jar files, I'd not go that route any more.

And as you link Tomcat 8.0 documentation: Make sure you're on a version of Tomcat that still gets update. At the time of answering this question, that's at least Tomcat 8.5

  • Related