与许多服务器应用程序同样,Tomcat安装了各类类加载器(即实现的类java.lang.ClassLoader),以容许容器的不一样部分和容器上运行的Web应用程序访问可用类和资源的不一样存储库。此机制用于提供Servlet规范2.4版中定义的功能 - 特别是9.4和9.6节。html
在Java环境中,类加载器排列在父子树中。一般,当要求类加载器加载特定的类或资源时,它首先将请求委托给父类加载器,而后仅在父类加载器找不到所请求的类或资源时查找它本身的存储库。 。请注意,Web应用程序类加载器的模型与此略有不一样,以下所述,但主要原则是相同的。java
当Tomcat启动时,它会建立一组类加载器,这些加载器被组织成如下父子关系,其中父类加载器位于子类加载器之上:web
Bootstrap | System | Common / \ Webapp1 Webapp2 ...
这些类加载器的特征,包括它们可见的类和资源的来源,将在下一节中详细讨论。数据库
如上图所示,Tomcat在初始化时建立如下类加载器:bootstrap
main()
方法,以及它依赖的类加载器实现类。若是tomcat-juli.jar是出如今 $CATALINA_BASE/bin 中,它被用来代替 $CATALINA_HOME/bin 中的那一个。它在某些日志记录配置中颇有用api
$CATALINA_HOME/bin/commons-daemon.jar - 来自Apache Commons Daemon项目的类。这个JAR文件不存在于CLASSPATH 由脚本catalina.bat|.sh 构建,可是从bootstrap.jar的清单文件中引用。tomcat
一般状况下,应用类应该不 放在这里。此类由common.loader加载器搜索的位置$CATALINA_BASE/conf/catalina.properties 中的属性定义。默认设置将按列出的顺序搜索如下位置:安全
默认状况下,这包括如下内容:服务器
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应用程序可见,但对其余应用程序不可见。websocket
如上所述,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应用程序的角度来看,类或资源加载按如下顺序查找如下存储库:
若是配置了Web应用程序类加载器 , <Loader delegate="true"/>
则清单顺序变为:
从Java 1.4开始,JRE中包含一个JAXP API和一个XML解析器。这会对但愿使用本身的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不彻底兼容),则存在Tomcat和/或部署的应用程序将出现错误的风险。
在安全管理器下运行时,容许加载类的位置也取决于策略文件的内容。有关详细信息,请参阅安全管理器HOW-TO。
还能够配置更复杂的类加载器层次结构。见下图。默认状况下, 未定义 Server 和 Shared 类加载器,并使用上面显示的简化层次结构。能够经过定义 server.loader
和/或 shared.loader
属性的值来使用这种更复杂的层次结构 conf/catalina.properties
。
Bootstrap | System | Common / \ Server Shared / \ Webapp1 Webapp2 ...
该服务器类加载器是惟一到Tomcat内部可见,而且是Web应用程序彻底不可见。
所述 Common 类加载器是将全部的web应用程序可见,而且能够在全部的 web 应用程序被用来共享代码。可是,对此共享代码的任何更新都须要从新启动Tomcat。