【问题标题】:How does Tomcat know which jar to choose for running a servlet?Tomcat 如何知道选择哪个 jar 来运行 servlet?
【发布时间】:2021-11-28 06:03:01
【问题描述】:

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

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

C:\projects\helloWorld\app 有一个 web-inf\lib 文件夹,其中包含一个 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?

【问题讨论】:

    标签: java tomcat servlets


    【解决方案1】:

    TLDR:

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

    长答案

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

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

    但是网络应用程序有一个 self-first 类加载器,它从自身加载类,只有当它失败时,它们才会尝试从父类加载。但也有一些例外:

    • 那些自我优先的类加载器不能覆盖 JRE 类
    • 而且他们总是“父优先”加载 JavaEE 类

    您可以在Apache Tomcat's docs 上阅读更多详细信息

    只要 servlet api 版本匹配,就不会有任何问题。但是如果你的 servlet 是针对不同的 api 版本编译的,例如它们是使用 Servlet v4 编译的,但是你尝试在 Servlet v3 环境中使用它们,你会得到运行时错误

    【讨论】:

    • 那么,在我的应用程序中,Tomcat 的 servlet-api.jar 类被加载了吗?
    • @Sara 没错
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    • 2016-08-04
    相关资源
    最近更新 更多