Tomcat如何知道选择哪个jar来运行servlet?



在我的项目中,Apache Tomcat 8.5 context.xml配置如下:

<Context path="/helloWorld" docBase="C:projectshelloWorldapp" crossContext="false" debug="0" reloadable="false"/>

C:projectshelloWorldapp有一个web-inflib文件夹,其中包含servlet.jar以及应用程序所需的其他jar文件。

此应用程序部署到Tomcat 8.5 web服务器上,并且%TOMCAT_HOME%lib文件夹还包含servlet-api.jar.

应用程序正常运行

我检查了两个jar和servlet.jar包含常规servlet api类,而tomcat的servlet-api.jar包含这些常规servlet api类以及许多其他servlet功能相关的类。

查询:既然有两个用于运行servlet的jar,即servlet.jar和servlet-api.jar,那么Tomcat如何知道在运行servlet时选择哪个jar呢?

TLDR:

Tomcat将加载它自己版本的servlet API,因为这是JavaEE规范所要求的。

长答案

JavaEE定义了如何加载和解析类。

类加载器通常是parent-first,即尝试从父类加载器加载类,只有当失败时,它们才尝试自己加载类。

但是web应用程序有一个self-first类加载器加载类的本身,只有在失败之后他们尝试加载的父母。但也有一些例外:

  • 这些自优先类加载器不能覆盖JRE类
  • 他们总是这样做&;parent-first&;加载JavaEE类

您可以在Apache Tomcat的文档

中了解更多详细信息。只要servlet api版本匹配,就不会有任何问题。但是,如果您的Servlet是针对不同的api版本编译的,例如,它们是使用Servlet v4编译的,但您试图在Servlet v3环境中使用它们,则会得到运行时错误