In my project, Apache Tomcat 8.5 context.xml is configured as follows.
<Context path="/helloWorld" docBase="C:\projects\helloWorld\app" crossContext="false" debug="0" reloadable="false"/>
C:\projects\helloWorld\app has a web-inf\lib folder which contains a servlet.jar along with the rest of the jars that the application needs.
This application is deployed to a Tomcat 8.5 web server and %TOMCAT_HOME%\lib folder also contains a servlet-api.jar.
The application is working as expected.
I have checked the two jars and servlet.jar contains the regular servlet api classes whereas tomcat's servlet-api.jar contains these regular servlet api classes along with many other servlet functionality related classes.
Query: Since there are two jars for running a servlet viz, servlet.jar and servlet-api.jar, how does Tomcat know which jar to pick up when running a servlet?
CodePudding user response:
TLDR:
Tomcat will load its own version of the servlet API, because this is required by the JavaEE specification.
The long answer
JavaEE defines how classes are loaded and resolved.
Usually class-loaders are parent-first - i.e. trying to load classes from the parent class-loader and only if that fails, they try to load the class themselves.
But web apps have a self-first class-loader which loads classes from itself and only if it fails then they try to load from the parent. But there are a few exceptions:
- those self-first class-loaders cannot override JRE classes
- and they always do "parent-first" loading of JavaEE classes
You can read about that in more details on the Apache Tomcat's docs
As long as the servlet api versions match there should not be any problems. But if your servlets are compiled against a different api version, for instance they are compiled using Servlet v4, but you try to use them in a Servlet v3 environment you will get runtime errors