本系列博客打算分析一下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包)
- 大小: 62 KB
- 大小: 25.4 KB
- 大小: 1.7 KB
- 大小: 29 KB
分享到:
相关推荐
《Tomcat类加载机制——ClassLoader详解》 在Java Web开发中,Tomcat作为最常用的Servlet容器,其类加载机制对于理解和优化应用性能至关重要。本文将深入探讨Tomcat的ClassLoader是如何工作的,以及它如何影响到...
尤其是Tomcat的ClassLoader机制,它是Java类加载的核心部分,对于理解和解决类加载问题至关重要。本文将围绕“Tomcat 5.0.18 ClassLoader源码”进行深入探讨。 ClassLoader在Java中承担着加载类到JVM中的任务,它的...
在深入了解Tomcat的工作原理时,一个重要的组成部分就是其ClassLoader机制。本文旨在深入剖析Tomcat中特有的类加载器(ClassLoader)体系结构,帮助读者理解Tomcat如何管理和加载不同类型的类库。 #### 二、Tomcat...
Apache Tomcat作为一款广泛使用的开源Servlet容器,其类加载机制是理解和维护基于Tomcat的应用程序的重要部分。Tomcat的类加载器遵循特定的加载顺序,确保了不同应用间的隔离性和资源的正确加载。下面将详细解析...
Java编程世界中,ClassLoader是一个至关重要的概念,尤其是在服务器端应用如Tomcat的环境中。本资料“Tomcat.ClassLoader.rar”聚焦于Java的类加载器(Class Loader)以及它在Tomcat容器中的工作原理,这对于理解和...
当`myApp`启动时,Tomcat会自动创建与`myApp`对应的ClassLoader,并通过`ContextBindings`将`jdbc/myDataSource`与该ClassLoader绑定。然后,在应用中,可以使用以下代码来获取数据源: ```java Context initCtx = ...
5. **ClassLoader机制**:Tomcat使用自定义的ClassLoader来加载Web应用程序的类,确保不同应用之间的类隔离,防止冲突。 Tomcat 6.0.18版的特性包括: 1. **性能优化**:相对于之前的版本,6.0.18进行了性能调优,...
本资料旨在帮助读者深入了解Tomcat的工作原理及其内部机制。 ### 一、Tomcat简介 Apache Tomcat是一款免费的开源Web服务器软件,主要用于支持Java Servlet、JavaServer Pages (JSP)技术以及部分Web服务标准规范。...
5. **ClassLoader机制**:Tomcat的类加载机制允许每个Web应用有自己的类加载器,这有助于隔离不同应用的类,防止类冲突。源码中包含了自定义ClassLoader的实现。 6. **配置文件解析**:Tomcat使用XML配置文件来定义...
5. **ClassLoader机制**:Tomcat的类加载机制允许每个Web应用拥有自己的类加载器,避免类冲突。理解这部分源码对于理解和解决部署问题至关重要。 6. **Session管理**:Tomcat处理用户会话,包括创建、跟踪和管理...
6. **ClassLoader机制** Tomcat使用自定义的ClassLoader来加载Web应用的类,这使得每个应用可以有自己的类空间,避免类冲突。Classloading策略是理解和调试Tomcat应用的重要部分。 7. **Session管理** Tomcat提供...
4. **ClassLoader机制**: Tomcat使用自定义的ClassLoader来加载Web应用的类,每个Web应用都有自己的独立ClassLoader,这种设计确保了应用间的类隔离,避免了类冲突。 5. **JNDI服务**: Tomcat提供JNDI(Java ...
Tomcat作为一款广泛使用的Java应用服务器,其类加载机制有着独特的设计,特别是对Java的双亲委派模型有所突破。本篇文章将深入探讨Tomcat如何打破双亲委派模型,并通过源码分析和图表解析来帮助理解这一机制。 首先...
Tomcat的类加载机制是其独特之处。主要有三个类加载器:Bootstrap ClassLoader、Common ClassLoader和Webapp ClassLoader。Bootstrap加载JDK的类,Common加载`common.loader`指定的类,而Webapp类加载器则负责加载...