本系列博客打算分析一下tomcat7.x的源码,其中可能会穿插一些java基础知识的介绍
读tomcat的源码的时候,我建议和官方的User Guide一起阅读,明白tomcat做某件事情的目的之后,看源码会容易一点。另外,debug当然是一个非常重要的工具。源码上了规模之后,如果单纯静态地看,基本是看不出什么来的,但是跟着数据流走一走,很多问题就清楚了
debug环境的搭建方法,请看另外一篇博客:http://zhh2009.iteye.com/blog/1557891。这篇文章写得很清楚了,但是我不太明白为什么需要转换成maven工程,以及为什么需要一个dist版本
作为本系列的第一篇文章,本文不涉及源码,首先介绍一下tomcat的classloader机制
参考的文档包括:
http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html
servlet-spec-2.4-fr
一、过时的模型
在网上搜索“tomcat classloader”,很容易搜索到下图,但是这是一个过时的模型
这个模型是在tomcat5.x使用的,可以看一下tomcat5.x的目录结构
再对比一下tomcat7.x的目录结构
可以看到,5.x里的server、shared、common目录,在7.x中已经废弃了。所以上图中的ClassLoader模型也是过时的
在tomcat7.x里,ClassLoader的模型应该是下图这样:
至于这个模型中,各个ClassLoader的具体作用,下文会说明
二、JVM默认的classloader机制
jvm默认定义了三种classloader,分别是bootstrap classloader、extension classloader、system classloader
bootstrap是jvm的一部分,用C写的,每一个java程序都会启动它,去加载%JAVA_HOME%/jre/lib/rt.jar
extension也差不多,它会去加载%JAVA_HOME%/jre/lib/ext/下的类
system则是会去加载系统变量CLASSPATH下的所有类
这3个部分,在上面的tomcat classloader模型图中都有体现。不过可以看到extension没有画出来,可以理解为是跟bootstrap合并了,都是去%JAVA_HOME%/jre/lib下面加载类
另外,java的classloader一般是采用委托机制,即classloader都有一个parent classloader,当它收到一个加载类的请求时,会首先请求parent classloader加载,如果parent classloader加载不到,才会自己去尝试加载(如果自己也加载不到,则抛出ClassNotFoundException)。采用这种机制的目的,主要是从安全角度考虑。比如用户自己定义了一个java.lang.Object,把jdk中的覆盖了,那显然是有问题的
当然,这个机制不是绝对的,比如在OSGi中,就故意违反了这个模式。后面可以看到,tomcat里的webapp classloader也违反了这个规定
三、tomcat为什么要自定义classloader
主要有2个目的,首先是要实现servlet规范中对类加载的要求,其次是实现不同web app的类隔离
servlet规范中对类加载要求如下:
This specification defines a hierarchical structure used for deployment and
packaging purposes that can exist in an open file system, in an archive file, or in some other form. It is recommended, but not required, that servlet containers
support this structure as a runtime representation.
Web applications can be packaged and signed into a Web ARchive format (WAR)
file using the standard Java archive tools. For example, an application for issue
tracking might be distributed in an archive file called issuetrack.war.
When packaged into such a form, a META-INF directory will be present which
contains information useful to Java archive tools. This directory must not be
directly served as content by the container in response to a Web client’s request, though its contents are visible to servlet code via the getResource and getResourceAsStream calls on the ServletContext. Also, any requests to access the
resources in META-INF directory must be returned with a SC_NOT_FOUND(404)
response.
四、各classloader详细说明
4.1 Bootstrap — This class loader contains the basic runtime classes provided by the Java Virtual Machine, plus any classes from JAR files present in the System Extensions directory ($JAVA_HOME/jre/lib/ext). Note: some JVMs may implement this as more than one class loader, or it may not be visible (as a class loader) at all.
4.2 System — 这个classloader通常是由CLASSPATH这个环境变量初始化的,通过这个classloader加载的所有类,都对tomcat自身的类,以及所有web应用的类可见。但是,标准的tomcat启动脚本($CATALINA_HOME/bin/catalina.bat),完全无视默认的CLASSPATH环境变量,而是加载了以下3个.jar
$CATALINA_HOME/bin/bootstrap.jar — Contains the main() method that is used to initialize the Tomcat server, and the class loader implementation classes it depends on.
$CATALINA_HOME/bin/tomcat-juli.jar — Logging implementation classes. These include enhancement classes to java.util.logging API, known as Tomcat JULI, and a package-renamed copy of Apache Commons Logging library used internally by Tomcat.
$CATALINA_HOME/bin/commons-daemon.jar — The classes from Apache Commons Daemon project.(这个类不是直接在$CATALINA_HOME/bin/catalina.bat里加进来的,不过在bootstrap.jar的manifest文件中包含进来了)
4.3 Common — 这个classloader加载的类,对tomcat的类和web app的类都是可见的。通常来说,应用程序的类不应该放在这里。该加载器的加载路径是在$CATALINA_BASE/conf/catalina.properties文件里,通过common.loader属性来定义的,默认是:
- common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar
By default, this includes the following:
annotations-api.jar — JavaEE annotations classes.
catalina.jar — Implementation of the Catalina servlet container portion of Tomcat.
catalina-ant.jar — Tomcat Catalina Ant tasks.
catalina-ha.jar — High availability package.
catalina-tribes.jar — Group communication package.
ecj-*.jar — Eclipse JDT Java compiler.
el-api.jar — EL 2.2 API.
jasper.jar — Tomcat Jasper JSP Compiler and Runtime.
jasper-el.jar — Tomcat Jasper EL implementation.
jsp-api.jar — JSP 2.2 API.
servlet-api.jar — Servlet 3.0 API.
tomcat-api.jar — Several interfaces defined by Tomcat.
tomcat-coyote.jar — Tomcat connectors and utility classes.
tomcat-dbcp.jar — Database connection pool implementation based on package-renamed copy of Apache Commons Pool and Apache Commons DBCP.
tomcat-i18n-**.jar — Optional JARs containing resource bundles for other languages. As default bundles are also included in each individual JAR, they can be safely removed if no internationalization of messages is needed.
tomcat-jdbc.jar — An alternative database connection pool implementation, known as Tomcat JDBC pool. See documentation for more details.
tomcat-util.jar — Common classes used by various components of Apache Tomcat.
4.4 WebappX — 该classloader加载所有WEB-INF/classes里的类,以及WEB-INF/lib里的jar
该classloader就有意违反了上述的委托模型,它首先看WEB-INF/classes和WEB-INF/lib里是否有请求的类,而不是委托parent classloader去加载。但是,JRE里定义的类不能被覆盖(比如java.lang.String),以及Servlet API会明确地被忽略。
前面说的bootstrap、system、common,都遵循普通的委托模型
4.5 总的来说,从web app的角度来看,类或者资源加载是按照以下的顺序来查找的:
Bootstrap classes of your JVM(rt.jar)
System class loader classes(bootstrap.jar、tomcat-juli.jar、commons-deamon.jar)
/WEB-INF/classes of your web application
/WEB-INF/lib/*.jar of your web application
Common class loader classes (在$CATALINA_HOME/lib里的jar包)
相关推荐
Tomcat是Apache软件基金会下的一个开源项目,是一个广泛使用的Java Servlet容器,特别因为其轻量级、高效能和稳定性而闻名。它实现了Java Servlet和JavaServer Pages(JSP)规范,使得开发者能够用Java语言来编写...
Tomcat7、Tomcat8和Tomcat9是不同版本的Tomcat,每个版本都有其特性和改进。 **Tomcat7**: Tomcat7是2011年发布的,它主要支持Java Servlet 3.0和JSP 2.2规范。这个版本引入了一些重要改进,包括增强的安全性、更...
Apache Tomcat 7.0是Java Servlet和JavaServer Pages(JSP)的开源Web应用程序服务器,由Apache软件基金会开发和维护。它是最流行的轻量级应用服务器,特别适合部署Java Web应用程序。Tomcat 7.0是7.x系列的一个版本...
Tomcat 7 和 Tomcat 8 是两个非常重要的版本,它们是Apache软件基金会开发的开源Java Servlet容器,主要用于运行Java Web应用程序。这两个版本都遵循Java EE(Enterprise Edition)规范,但各自具有不同的特点和改进...
Apache Tomcat是一款广泛应用的开源Java Servlet容器,它实现了Java EE的Web部分,特别是Servlet和JSP规范。在本文中,我们将深入探讨Tomcat 7.0.0的安装版和7.0.11的免安装版之间的差异,以及如何进行安装和配置。 ...
版本:apache-tomcat-10.1.23 Tomcat 10 是 Apache Tomcat 的一个版本,它引入了一些新的功能和改进。以下是一些关键的新增功能: 1. JDK 11 支持:Tomcat 10 支持 JDK 11,这意味着它可以用于 JDK 11 的项目中。 2....
在Linux(CentOS7)操作系统中安装Apache Tomcat并将其设置为开机启动是一项常见的任务,特别是在部署Java web应用时。本篇文章将详细讲解如何在CentOS7上安装Tomcat8并将其配置为自启动服务。 首先,我们来了解...
tomcat
标题中的“tomcat6”指的是Apache Tomcat 6,这是一个开源的应用服务器,主要用来部署和运行Java Servlet和JavaServer Pages(JSP)应用程序。在Java Web开发领域,Tomcat是应用最广泛的轻量级服务器之一,尤其对于...
### Tomcat打补丁方法详解 #### 一、前言 Apache Tomcat是一款开源的Servlet容器,它能够作为Web服务器独立运行,也可以与Apache等其他Web服务器配合使用。Tomcat因其简单性和灵活性,在中小型项目中得到了广泛...
《Tomcat深入剖析》这本书是理解Apache Tomcat服务器工作原理的宝贵资料,它由美国作者撰写并被翻译成中文,适合各个层次的开发者阅读。通过深入学习,读者能够对Tomcat的内部机制有全面而深入的理解,从而更好地...
tomcat-redis-session-manager-1.2-tomcat-7-java-7tomcat-redis-session-manager-1.2-tomcat-7-java-7tomcat-redis-session-manager-1.2-tomcat-7-java-7tomcat-redis-session-manager-1.2-tomcat-7-java-7tomcat-...
《深入理解Tomcat-Redis-Session-Manager:在Tomcat7和Tomcat8中的应用》 在现代Web应用程序开发中,session管理是一个至关重要的环节,它涉及到用户会话的持久化和跨请求的数据共享。传统的session管理方式在高...
在Java Web应用服务器Tomcat 6中,日志管理是一个至关重要的部分,它帮助开发者跟踪应用程序的运行状态,排查问题,以及记录系统活动。这里提到的`tomcat-juli.jar`、`tomcat-juli-adapters.jar`和`log4j-1.2.12.jar...
Apache Tomcat 7.0.52 是一个广泛使用的开源软件,它是一个实现了Java Servlet、JavaServer Pages(JSP)和Java EE的Web应用程序容器。这个版本是免安装的,这意味着用户无需经过复杂的安装过程,只需解压到指定目录...
标题中的“tomcat7.0下的64位的tomcat7.exe 和tomcat7w.exe”指的是Apache Tomcat服务器在7.0版本中为64位操作系统提供的可执行文件。Tomcat是Apache软件基金会的一个开源项目,它是一个流行的Java Servlet容器,...
**Idea Tomcat Runner插件详解** 在Java开发领域,IntelliJ IDEA是一款备受推崇的集成开发环境(IDE),尤其以其高效、智能的代码编辑功能和丰富的插件生态而著称。对于使用Java Web应用的开发者来说,Tomcat服务器...
在Java Web应用中,Tomcat是一个广泛使用的开源应用服务器,它提供了Servlet容器和JSP引擎等核心功能。在处理数据库连接方面,Tomcat提供了一种高效且可管理的数据源实现,名为“tomcat-jdbc数据源”。这个数据源是...
Apache Tomcat 7是Apache软件基金会的一个开源项目,专门用于实现Java Servlet和JavaServer Pages(JSP)技术的标准,以及Java EE的Web应用程序部署。这个最新版本,即7.0.109,包含了对先前版本的改进和修复,旨在...
标题中的"tomcat-7.0.108.zip"是一个Tomcat服务器的特定版本,这里指的是Apache Tomcat 7.0.108。Tomcat是一款开源的Java Servlet容器,主要用于运行Java web应用程序,包括JSP和Servlet。这个版本号(7.0.108)表明...