【Tomcat】【源码一】Tomcat 源码分析环境搭建
1 前言
Apache Tomcat®软件是Java Servlet、JavaServer页面、Java 语言表达式和 Java WebSocket 技术的开源实现。Java Servlet、JavaServer页面、Java 表达式语言和 Java WebSocket 规范都是在 Java 社区进程下开发的。
Apache Tomcat 软件是在开放和参与的环境中开发的,并在 Apache 许可版本 2 下发布。Apache Tomcat 项目旨在成为世界各地最优秀的开发人员的协作项目。我们邀请您参与这个开放的开发项目。要了解更多关于参与的信息,请点击这里。
Apache Tomcat 做为标准的 Java Servlet 规范的标准实现。在 Java 企业级开发中,很多企业都是基于 Tomcat 来发布应用,尤其是 Spring Boot 默认内置 Tomcat 做为 Servlet 容器。我们有必要去学习 Tomcat 源码,这样我们可以更好的使用并且优化 Tomat。
参考:https://blog.csdn.net/u012410733/article/details/105544643
2 下载 Tomcat 源码
8、9、10版本的下载:https://tomcat.apache.org/
6以及以前的版本下载:https://archive.apache.org/dist/tomcat/tomcat-6/ (jdk不能大于8,否则不兼容)
由于博主使用的是 Mac 操作系统所以下载的是 tar.gz
格式的文件。如果使用 window 操作系统,可以下载 zip
格式的文件.
解析源码压缩包,可以得到源码项目 apache-tomcat-8.5.54-src
。
3 添加 pom.xml
Tomcat 的依赖管理是使用的 ant,但是现在企业基本上都使用 maven 进行项目的依赖管理。
进入apache-tomcat-8.5.54-src
目录,创建一个 pom.xml 文件,文件内部如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.apache.tomcat</groupId> <artifactId>apache-tomcat-8.5.53-src</artifactId> <name>Tomcat8.5</name> <version>8.5</version> <build> <!--指定源目录--> <finalName>Tomcat8.5</finalName> <sourceDirectory>java</sourceDirectory> <resources> <resource> <directory>java</directory> </resource> </resources> <plugins> <!--引入编译插件,指定编译级别和编码--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <encoding>UTF-8</encoding> <source>8</source> <target>8</target> </configuration> </plugin> </plugins> </build> <!--Tomcat是java开发的,封装了很多功能,它需要依赖一些基础的jar包--> <dependencies> <!--远程过程调用工具包--> <dependency> <groupId>javax.xml</groupId> <artifactId>jaxrpc</artifactId> <version>1.1</version> </dependency> <!--soap协议处理工具包--> <dependency> <groupId>javax.xml.soap</groupId> <artifactId>javax.xml.soap-api</artifactId> <version>1.4.0</version> </dependency> <!--解析webservice的wsdl文件工具--> <dependency> <groupId>wsdl4j</groupId> <artifactId>wsdl4j</artifactId> <version>1.6.2</version> </dependency> <!--Eclipse Java编译器--> <dependency> <groupId>org.eclipse.jdt.core.compiler</groupId> <artifactId>ecj</artifactId> <version>4.5.1</version> </dependency> <!--ant管理工具--> <dependency> <groupId>ant</groupId> <artifactId>ant</artifactId> <version>1.7.0</version> </dependency> <!---easymock辅助单元测试--> <dependency> <groupId>org.easymock</groupId> <artifactId>easymock</artifactId> <version>3.4</version> </dependency> </dependencies> </project>
4 创建配置文件 source
Tomcat 本身就是 Java 开发邮的一款软件。我们在直接使用 Tomcat 的时候,Tomcat 需要读取 server.xml 以及其它配置文件,同时还需要找到它要去部署的工程项目。使用源码方式,依赖是如此的。
所以我们在启动源码进行调试时,需要在通过指定虚拟机参数把项目配置文件传递进去。
将 apache-tomcat-8.5.54-src 目录下的 conf 和 webapps 目录移动到刚刚创建的 source 目录当中。
5 Idea 导入 Tomcat 源码
下面就需要把 Tomcat 源码导入到 Idea 当中。
刚开始导入的时候,pom.xml 中依赖的有些 Jar 包还没有下载,就会出现依赖问题。就需要执行 mvn clean install
编译下载 pom.xml 中依赖的 Jar 包。
6 启动 Tomcat
Tomcat 的入口类是 org.apache.catalina.startup.Bootstrap
,接着就是启动这个入口类。当然为了正常启动还需要添加以下启动参数。
-Dcatalina.home=/Users/carl/projects/idea/learn/apache-tomcat-8.5.54-src/source
-Dcatalina.base=/Users/carl/projects/idea/learn/apache-tomcat-8.5.54-src/source
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djava.util.logging.config.file=/Users/carl/projects/idea/learn/apache-tomcat-8.5.54-src/source/conf/logging.properties
windows的:
-Dcatalina.home=D:\JetBrains\yanjiu\apache-tomcat-8.5.93-src\source
-Dcatalina.base=D:\JetBrains\yanjiu\apache-tomcat-8.5.93-src\source
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djava.util.logging.config.file=D:\JetBrains\yanjiu\apache-tomcat-8.5.93-src\source\conf\logging.properties
7 Q & A
7.1 控制台乱码
Tomcat 里面是实现了 i18n 也就是国际化的,所以在启动的时候会出现乱码问题。虽然 Tomcat 的中文国际化文件的编码格式是 utf-8,但是 Java 国际化 ResourceBundle 在读取的时候默认使用的是 ISO-8859-1
而且处理类还不能够传入编码。
所以在处理 Tomcat 启动乱码时需要修改以下两点:
第一个修改点
org.apache.tomcat.util.res.StringManager#getString(java.lang.String)
# @位置:org.apache.tomcat.util.res.StringManager
# @方法 getString()
# @Line:130行
str = bundle.getString(key)
替换成下面代码:
str = new String(bundle.getString(key).getBytes("ISO-8859-1"), "UTF8");
第二个修改点:
org.apache.jasper.servlet.TldScanner#scanJars
log.info(Localizer.getMessage("jsp.tldCache.noTldSummary"));
替换成下面代码:
String message = Localizer.getMessage("jsp.tldCache.noTldSummary");
String logger = new String(message.getBytes("ISO-8859-1"), "UTF8");
log.info(logger);
以下就是修改代码后的控制台打印日志:
7.2 访问 Tomcat 500
当启动 Tomcat 成功之后访问 localhost:8080
时,会出现 500 异常。
原因是 Tomcat 源码中 JSP 引擎 jasper 没有被初始化,从而无法编译处理 JSP(因为 JSP 是需要被转换成 Servlet 进一步编译处理的)。我们只需要在 Tomcat 的源码 ContextConfig 类中的 configureStart 方法中增加一行代码将 JSP 引擎初始化,如下:
ContextConfig#configureStart
// 读取 Web 项目配置 (web.xml 配置)
webConfig();
// 初始化 jsp 引擎 (下面是添加的代码)
context.addServletContainerInitializer(new JasperInitializer(), null);
然后就可以正常访问了。
7.3 访问 Tomcat 提供的 Examples 报 404
访问 ${tomcat.project}/source/webapps/examples
提供的 Examples 。
会报 404 异常:
解决办法:${tomcat.project}/source/webapps/examples/WEB-INF/classes
右击 Mark Directory as sources Root
。
标记之后图标会从灰色变成蓝色,接着就重启 Tomcat 源码。然后就可以正常的访问 localhost:8080/examples
8 小结
一步一步走下来,我的是可以启动成功的,6以及之前的版本需要的 JDK是7 ,高版本的不兼容奥,我是整了两个一个8版本、一个6版本 对比着看,也感谢博主哈。