The Jakarta Project
      The Apache Jakarta Tomcat Servlet/JSP Container

链接

用户指南

参考

开发 Tomcat

The Apache Jakarta Tomcat 5 Servlet/JSP Container

Class Loader HOW-TO

Printer Friendly Version
print-friendly
版本
快速上手(Quick Start)

程序开发员和部署员要决定在哪里放置类和资源文件以便它们可以被网络程序使用, 95%的这些决定由下面的这些条例覆盖:

  • 对于某个网络程序所特有的类和资源,把这些未包装的类和资源放置在你的网络程序档案/WEB-INF/classes目录下面,或者把包含这些类和资源的JAR文件放置在你的网络程序档案/WEB-INF/lib目录下面。
  • 对于必须被所有网络程序所共享的类和资源,把未包装的这些类和资源放置在$CATALINA_BASE/shared/classes下面,或者把包含这些类和资源的JAR文件放置在$CATALINA_BASE/shared/lib下面。
概述

象许多服务器程序一样,Tomcat 5安装各种不同类型的类loaders(那就是,实现java.lang.ClassLoader的类)来允许容器的不同部分,以及运行在容器上的网络程序,可以访问不同贮存部分的类和资源。这个机制是用来提供Servlet Specification, 2.4版——特别是9.4 和 9.6章节里定义的功能。

在Java 2 (就是, JDK 1.2 或其后版本)环境里,类装载器(class loaders)被排列成父子树的形式。通常,当一个类装载器被要求装载某个特定的类或资源时,它首先把这个请求派送到父辈类装载器,只有当父辈类装载器不能找到需要的类或资源时,才在自己的贮藏室里寻找。网络程序的类装载器模式与下面讨论的有细微的区别,但是主要的原理是一样的。

当Tomcat 5启动后,它产生一组类装载器,这些类装载器被组织成如下的父子关系,父类装载器在子类装载器之上:

Bootstrap 
| 
System 
| 
Common 
/  
Catalina Shared 
/  
Webapp1 Webapp2 ...

每一个类装载器的特征,包括可被使用的类和资源的来源,在下面的章节有详细讨论。

类装载器定义

如上面的图表显示,Tomcat 5在它启动时产生如下的类装载器:

  • Bootstrap - 这个类装载器包含Java虚拟器提供的基本的运行时间类,加上在System Extensions 目录( $JAVA_HOME/jre/lib/ext )里的JAR文件中所有的类。注意——有些Java虚拟器(JVMs)也许把它作为不止一个类装载器用,或者作为一个类装载器用。
  • System - 这个类装载器通常是以CLASSPATH环境变量的内容为基础来初始化的。所有的这些类既可被Tomcat内部classes使用,又可被网络程序使用。不过,标准的Tomcat 5启动脚本( $CATALINA_HOME/bin/catalina.sh or %CATALINA_HOME%\bin\catalina.bat )完全忽略了CLASSPATH环境变量自身的内容,相反从下面的贮藏室去建造系统类装载器:
    • $CATALINA_HOME/bin/bootstrap.jar - 包含用来初始化Tomcat 5服务器的main()方法,以及它所依赖的类装载器执行类。
    • $JAVA_HOME/lib/tools.jar - 包含用来把JSP页面转换成servlet类的"javac"编译器。
    • $CATALINA_HOME/bin/commons-logging-api.jar - Jakarta commons 记录应用程序界面。
    • $CATALINA_HOME/bin/commons-daemon.jar - Jakarta commons daemon API.
    • jmx.jar - JMX 1.2 执行。
  • Common - 这个类装载器包含既可被Tomcat内部classes使用,又可被所有网络程序使用的额外的类。通常,应用程序的类不应该被放置在这里。所有的在$CATALINA_HOME/common/classes里的未包装的类和资源,以及在$CATALINA_HOME/commons/endorsed 和$CATALINA_HOME/common/lib 目录下面 JAR文件里的类和资源,都通过这个类装载器使它们可以被利用。在默认的情况下,包括下面的这些类:  NOT
    • ant.jar - Apache Ant。
    • commons-collection.jar - Jakarta commons collection 。
    • commons-dbcp.jar - Jakarta commons DBCP, providing a JDBC connection pool to web applications.
    • commons-el.jar - Jakarta commons el, 执行Jasper使用的表达语言。
    • commons-pool.jar - Jakarta commons pool 。
    • jasper-compiler.jar - The JSP 2.0 编译器。
    • jasper-runtime.jar - The JSP 2.0 运行时间。
    • jsp-api.jar - The JSP 2.0 应用编程界面(API)。
    • naming-common.jar - 被Tomcat 5用来代表in-memory命名contexts的JNDI实现。
    • naming-factory.jar - 被Tomcat 5用来决定企业资源索引(EJB, connection pools)的JNDI实现。
    • naming-resources.jar - 用来代表网络程序静态资源的特殊JNDI naming context实现。
    • servlet-api.jar - The Servlet and JSP API classes 。
    • xerces.jar - 可被Tomcat内部类和网络程序使用的默认XML语发分析式。
  • Catalina - 这个类装载器被初始化后包含执行Tomcat 5自身必须的所有类和资源。这些类和资源完全可被网络程序使用。所有的在$CATALINA_HOME/server/classes里未包装的类和资源,以及$CATALINA_HOME/server/lib下JAR文件里的类和资源,通过这个类装载器可被使用。在默认的情况下,有下面的这些:
    • catalina.jar - Tomcat 5的执行Catalina servlet容器部分。
    • jakarta-regexp-X.Y.jar - Jakarta Regexp常规表达处理库的二进制分布,它被用在执行请求过滤(request filters)中。
    • servlets-xxxxx.jar - 与每个内部servlet相关联的类,这些内部servlet提供一部分Tomcat的功能。它们是分离开的,这样一来,如果相应的服务不需要的话,它们就可以完全被删除,或者它们需要特别的安全管理员许可。
    • tomcat-coyote.jar - Tomcat 5 Coyote 连接器。
    • tomcat-http11.jar - 独立的Java HTTP/1.1 连接器。
    • tomcat-jk2.jar - JK 2 web server连接器的Java 部分的类,JK 2 web server连接器允许Tomcat在诸如Apache,iPlanet iAS,iWS这些网络服务器后面运行。
    • tomcat-util.jar - 一些Tomcat必需的Utility类。
  • Shared - 这个类装载器是放置被所有网络程序共享的类和资源的地方(除非Tomcat内部classes也需要访问它们,要是这样,你就得把它们放在Common这个类装载器)。所有的在$CATALINA_BASE/shared/classes 里未包装的类和资源,以及$CATALINA_BASE/shared/lib 下JAR文件里的类和资源,通过这个类装载器可被使用。如果多个Tomcat实例使用同样的$CATALINA_BASE环境变量运行,那么这个类装载器的储藏室就和$CATALINA_BASE有关,而不是和$CATALINA_HOME有关。
  • WebappX - 为在单个Tomcat 5实例中被部署的每一个网络程序所产生的类装载器。在你的网络程序档案/WEB-INF/classes目录里所有的未包装的类和资源,以及网络程序档案/WEB-INF/lib目录下JAR文件里的类和资源,可被这个Webapp里的程序使用,而不能其他程序使用。

正如上面所说,网络程序的类加载器与默认的Java 2 delegation model (Servlet Specification, 2.3版, 9.7.2 章里所推荐的网络程序类加载器)有分歧。 当一个从网络程序的WebappX类加载器来的装载一个类的请求被处理时,这个类加载器将首先在局部的贮藏室查找,而不是在查找之前就delegating。当然也有例外。作为JRE base classes 一部分的类不能被覆盖。对于一些类(如the XML parser components in JDK 1.4+), JDK 1.4支持的特性可以被使用(参看上面的common classloader定义)。另外,对于下面的类的式样,类加载器总是首先delegate(并装载它自身的类,如果父类加载器没有装载的话)。

  • javax.*
  • org.xml.sax.*
  • org.w3c.dom.*
  • org.apache.xerces.*
  • org.apache.xalan.*
最后,任何包含servlet API类的JAR将被类装载器忽略掉。Tomcat 5里所有的的其他类装载器遵守通常delegation模式。

因此,从一个网络程序的角度来看,类和资源的装载以这样的顺序在下列贮藏室进行查找:

  • 你的JVM的Bootstrap类
  • 系统类装载器类(描述如上)
  • 你的网络程序的/WEB-INF/classes
  • 你的网络程序的/WEB-INF/lib/*.jar
  • $CATALINA_HOME/common/classes
  • $CATALINA_HOME/common/endorsed/*.jar
  • $CATALINA_HOME/common/lib/*.jar
  • $CATALINA_BASE/shared/classes
  • $CATALINA_BASE/shared/lib/*.jar
XML语法分析式与JDK 1.4

在许多改变当中,JDK 1.4发行了the JAXP APIs软件包,以及一种版本的Xerces 。这对希望使用它们自己的XML语法分析式的程序有影响。

在以前的Tomcat 5版本里,你可以简单地取代$CATALINA_HOME/common/lib目录里的XML语法分析式就可以取代被所有网络程序使用的语法分析式。但是,当你在JDK 1.4上运行时,这个技术就无效了,因为通常的类装载delegation process总是选择在JDK里面的implementation,而不是这个。

JDK 1.4支持被称为"Endorsed Standards Override Mechanism" 的机制,来允许替代在JCP以外产生的APIs(例如DOM 和W3C里的SAX)。也可以使用它来更新XML语法分析式执行。更多信息,请参看http://java.sun.com/j2se/1.4/docs/guide/standards/index.html 。

Tomcat通过在启动容器的命令行里加入系统属性设置-Djava.endorsed.dirs=$CATALINA_HOME/common/endorsed 来利用这个机制。因此,你可以取代安装在这个目录里的语法分析式,它甚至可以在JDK 1.4系统上使用。

在安全管理下运行

当在一个安全管理者下面运行时,从什么地方来的类可以被装载依赖于你的政策文件的具体内容。更多信息请参看Security Manager HOW-TO


Copyright © 1999-2003, Apache Software Foundation