Tomcat7 类加载器操作指南

Tomcat7类加载器操作指南

目录
概述

与许多服务器应用程序一样,Tomcat 安装了各种类加载器(即实现 的类java.lang.ClassLoader)以允许容器的不同部分以及在容器上运行的 Web 应用程序访问可用类和资源的不同存储库。此机制用于提供 Servlet 规范 2.4 版中定义的功能,尤其是第 9.4 和 9.6 节。

在 Java 环境中,类加载器排列在父子树中。通常,当类加载器被要求加载特定的类或资源时,它首先将请求委托给父类加载器,然后仅在父类加载器找不到请求的类或资源时才在自己的存储库中查找. 请注意,Web 应用程序类加载器的模型此略有不同,如下所述,但主要原理是相同的。

当 Tomcat 启动时,它会创建一组类加载器,这些类加载器组织成以下父子关系,其中父类加载器位于子类加载器之上:

      Bootstrap
          |
       System
          |
       Common
       /     \
  Webapp1   Webapp2 ...

这些类加载器中的每一个的特性,包括它们使可见的类和资源的来源,将在下一节中详细讨论。

类加载器定义

如上图所示,Tomcat 在初始化时会创建以下类加载器:

  • Bootstrap — 该类加载器包含 Java 虚拟机提供的基本运行时类,以及系统扩展目录 ( $JAVA_HOME/jre/lib/ext) 中存在的 JAR 文件中的任何类。 注意:一些 JVM 可能将其实现为多个类加载器,或者它可能根本不可见(作为类加载器)。

  • System——这个类加载器通常从CLASSPATH环境变量的内容中初始化。所有这些类对 Tomcat 内部类和 Web 应用程序都是可见的。但是,标准的 Tomcat 启动脚本($CATALINA_HOME/bin/catalina.sh或 %CATALINA_HOME%\bin\catalina.bat)完全忽略了CLASSPATH环境变量本身的内容,而是从以下存储库构建 System 类加载器:

    • $CATALINA_HOME/bin/bootstrap.jar — 包含用于初始化 Tomcat 服务器的 main() 方法,以及它所依赖的类加载器实现类。

    • $CATALINA_BASE/bin/tomcat-juli.jar或 $CATALINA_HOME/bin/tomcat-juli.jar — 日志实现类。其中包括java.util.loggingAPI 的增强类 ,称为 Tomcat JULI,以及 Tomcat 内部使用的 Apache Commons Logging 库的包重命名副本。有关更多详细信息,请参阅日志记录文档

      如果tomcat-juli.jar存在于 $CATALINA_BASE/bin 中,则使用它代替$CATALINA_HOME/bin 中的那个 。它在某些日志记录配置中很有用

    • $CATALINA_HOME/bin/commons-daemon.jar — 来自Apache Commons Daemon项目的类。这个 JAR 文件不存在于CLASSPATH构建者 catalina.bat.sh脚本,但从bootstrap.jar的清单文件中引用。

  • Common——这个类加载器包含对 Tomcat 内部类和所有 Web 应用程序都可见的附加类。

    通常情况下,应用类应该 放在这里。此类加载器搜索的位置由common.loader$CATALINA_BASE/conf/catalina.properties 中的属性定义。默认设置将按照列出的顺序搜索以下位置:

    • 解压的类和资源 $CATALINA_BASE/lib
    • JAR 文件在 $CATALINA_BASE/lib
    • 解压的类和资源 $CATALINA_HOME/lib
    • JAR 文件在 $CATALINA_HOME/lib

    默认情况下,这包括以下内容:

    • annotations-api.jar — JavaEE 注释类。
    • catalina.jar — Tomcat 的 Catalina servlet 容器部分的实现。
    • catalina-ant.jar — Tomcat Catalina Ant 任务。
    • catalina-ha.jar — 高可用性包。
    • catalina-tribes.jar — 群组通讯包。
    • ecj-*.jar — Eclipse JDT Java 编译器。
    • el-api.jar — EL 2.2 API。
    • jasper.jar — Tomcat Jasper JSP 编译器和运行时。
    • jasper-el.jar — Tomcat Jasper EL 实现。
    • jsp-api.jar — JSP 2.2 API。
    • servlet-api.jar — Servlet 3.0 API。
    • tomcat-api.jar — Tomcat 定义的几个接口。
    • tomcat-coyote.jar — Tomcat 连接器和实用程序类。
    • tomcat-dbcp.jar — 基于 Apache Commons Pool 和 Apache Commons DBCP 1.x 的包重命名副本的数据库连接池实现。
    • tomcat-i18n-**.jar — 包含其他语言资源包的可选 JAR。由于默认包也包含在每个单独的 JAR 中,如果不需要消息的国际化,可以安全地删除它们。
    • tomcat-jdbc.jar — 另一种数据库连接池实现,称为 Tomcat JDBC 池。有关更多详细信息,请参阅 文档
    • tomcat-util.jar — Apache Tomcat 的各种组件使用的通用类。
    • tomcat7-websocket.jar — WebSocket 1.1 实现
    • websocket-api.jar — WebSocket 1.1 API
  • WebappX — 为部署在单个 Tomcat 实例中的每个 Web 应用程序创建一个类加载器。/WEB-INF/classesWeb 应用程序目录中的所有解压类和资源,以及 Web 应用程序/WEB-INF/lib目录下 JAR 文件中的类和资源,都对这个 Web 应用程序可见,但对其他 Web 应用程序不可见。

如上所述,Web 应用程序类加载器不同于默认的 Java 委托模型(根据 Servlet 规范 2.4 版第 9.7.2 节 Web 应用程序类加载器中的建议)。当加载从Web应用程序的一个类的请求WebappX被处理的类加载器,这个类加载器会在本地资源库第一,而不是在查看之前委托。有例外。作为 JRE 基类一部分的类不能被覆盖。对于某些类(例如 J2SE 1.4+ 中的 XML 解析器组件),Java 认可的特性可以在 Java 8 之前使用。最后,类加载器将显式忽略包含 Servlet API 类的任何 JAR 文件 — 请勿包含此类Web 应用程序中的 JAR。Tomcat 中的所有其他类加载器都遵循通常的委托模式。

因此,从 Web 应用程序的角度来看,类或资源加载按以下顺序查看以下存储库:

  • JVM 的引导类
  • 您的 Web 应用程序的/WEB-INF/classes
  • 您的 Web 应用程序的/WEB-INF/lib/*.jar
  • 系统类加载器类(如上所述)
  • 常见的类加载器类(如上所述)

如果配置了 Web 应用程序类加载器 , <Loader delegate="true"/> 则顺序变为:

  • JVM 的引导类
  • 系统类加载器类(如上所述)
  • 常见的类加载器类(如上所述)
  • 您的 Web 应用程序的/WEB-INF/classes
  • 您的 Web 应用程序的/WEB-INF/lib/*.jar
XML 解析器和 Java

从 Java 1.4 开始,JAXP API 的副本和 XML 解析器被打包在 JRE 中。这会对希望使用自己的 XML 解析器的应用程序产生影响。

在旧版本的 Tomcat 中,您可以简单地替换 Tomcat 库目录中的 XML 解析器来更改所有 Web 应用程序使用的解析器。但是,当您运行 Java 的现代版本时,这种技术将无效,因为通常的类加载器委托过程总是会优先选择 JDK 内部的实现而不是这个。

Java 支持一种称为“认可标准覆盖机制”的机制,以允许替换在 JCP 之外创建的 API(即来自 W3C 的 DOM 和 SAX)。它还可用于更新 XML 解析器实现。有关更多信息,请参阅: http : //docs.oracle.com/javase/1.5.0/docs/guide/standards/index.html

Tomcat 通过-Djava.endorsed.dirs=$JAVA_ENDORSED_DIRS在启动容器的命令行中包含系统属性设置来利用此机制 。此选项的默认值为 $CATALINA_HOME/endorsed。默认情况下不创建此认可目录。请注意,Java 9 不再支持已背书功能,并且只有在$CATALINA_HOME/endorsed目录存在或JAVA_ENDORSED_DIRS已设置变量 时才会设置上述系统属性。

请注意,覆盖任何 JRE 组件都会带来风险。如果覆盖组件不提供 100% 兼容的 API(例如,Xerces 提供的 API 与 JRE 提供的 XML API 不是 100% 兼容),则存在 Tomcat 和/或部署的应用程序会遇到错误的风险。

在安全管理器下运行

在安全管理器下运行时,允许加载类的位置也取决于策略文件的内容。有关 详细信息,请参阅安全管理器操作方法

高级配置

还可以配置更复杂的类加载器层次结构。见下图。默认情况下, 未定义ServerShared类加载器,而是使用上面显示的简化层次结构。可以通过为 中的server.loader和/或shared.loader属性 定义值来使用这种更复杂的层次结构 conf/catalina.properties


  Bootstrap
      |
    System
      |
    Common
     /  \
Server  Shared
         /  \
   Webapp1  Webapp2 ...

服务器类加载器是唯一到Tomcat内部可见,并且是Web应用程序完全不可见。

所述共享类加载器是将所有的web应用程序可见,并且可以在所有的web应用程序被用来共享代码。但是,对此共享代码的任何更新都需要重新启动 Tomcat。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值