Tomcat源码分析一:编译Tomcat源码
tomcat源码分析一:编译tomcat源码
1 内容介绍
在之前的《servlet与tomcat运行示例》一文中,给大家带来如何在tomcat中部署servlet应用的相关步骤,本文将就上文为基础,开始tomcat源码分析之旅,我将详细的分析tomcat的启动过程及运行原理。本文将是最基础的一节课,也就是本地编译好tomcat源码,为后面的分析做基础!
2 编译tomcat源码
2.1 下载tomcat源码
我们去tomcat官网下载最新的tomcat源码包,目前最新的版本为9.0.26,我们下载其source源码包tar.gz版本,如下图:
2.2 解压源码包apache-tomcat-9.0.26-src.tar.gz
解压源码包apache-tomcat-9.0.26-src.tar.gz之后得到的内容为:
2.3 解压后的文件夹中添加pom.xml
因为要使用maven的方式导入tomcat项目,故需要添加相应的maven依赖,此处添加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>com.github.sources</groupid> <artifactid>source-tomcat</artifactid> <version>9.0.26</version> <name>source-tomcat</name> <dependencies> <dependency> <groupid>junit</groupid> <artifactid>junit</artifactid> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupid>org.easymock</groupid> <artifactid>easymock</artifactid> <version>3.5.1</version> </dependency> <dependency> <groupid>org.apache.ant</groupid> <artifactid>ant</artifactid> <version>1.10.1</version> </dependency> <dependency> <groupid>wsdl4j</groupid> <artifactid>wsdl4j</artifactid> <version>1.6.2</version> </dependency> <dependency> <groupid>javax.xml</groupid> <artifactid>jaxrpc</artifactid> <version>1.1</version> </dependency> <dependency> <groupid>org.eclipse.jdt</groupid> <artifactid>org.eclipse.jdt.core</artifactid> <version>3.18.0</version> </dependency> <dependency> <groupid>org.eclipse.jdt.core.compiler</groupid> <artifactid>ecj</artifactid> <version>4.6.1</version> </dependency> </dependencies> <build> <finalname>tomcat9.0</finalname> <sourcedirectory>java</sourcedirectory> <testsourcedirectory>test</testsourcedirectory> <resources> <resource> <directory>java</directory> </resource> </resources> <testresources> <testresource> <directory>test</directory> </testresource> </testresources> <plugins> <plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-compiler-plugin</artifactid> <version>3.6.1</version> <configuration> <encoding>utf-8</encoding> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
2.4 idea导入tomcat源码工程
使用idea开发工具,以maven的方式导入tomcat工程,导入之后工程结构如下:
2.5 启动tomcat工程
运行org.apache.catalina.startup
包下的bootstrap类的main方法
此时,我们发现了一些错误,下面我们来解决这些错误。
3 异常问题解决
3.1 trailers.responsetrailers不存在
我们可以去webapps/examples/web_inf/classes/trailers
目录下找到该类,我们将这个类复制一份到test下:
拷贝完成之后的情况如下:
3.2 cookiefilter不存在
同样,我们去将home\webapps\examples\web-inf\classes\util\cookiefilter.java
文件拷贝到 test\util
目录下:
3.3 filenotfoundexception: /library/apachetomcat/source/test/source-tomcat/conf/server.xml (no such file or directory)
在解决上述3.1和3.2的问题之后,又出现了下图所示的问题:
- 解决方案:
在启动的配置中,添加vm options的参数,添加项目路径,本机为/library/apachetomcat/source/test/apache-tomcat-9.0.26-src
,故而添加参数内容为:-dcatalina.home=/library/apachetomcat/source/test/apache-tomcat-9.0.26-src
, 如下图所示:
3.4 java.lang.classnotfoundexception: listeners.contextlistener
在解决上述3.3问题之后,再次启动bootstrap类的main方法,程序出现以下错误信息:
- 解决方案: 删除 webapps 下的 examples 文件夹!程序再次运行不报此错误!
3.5 servlet.service() for servlet [jsp] in context with path [] threw exception [org.apache.jasper.jasperexception: unable to compile class for jsp] with root cause
在解决上述问题之后,启动bootstrap类的main方法,程序正常启动,此时我们在浏览器访问127.0.0.1:8080
, 程序出现以下错误信息:
- 解决方案:编辑 org.apache.catalina.startup.contextconfig 文件的 configurestart() 方法,添加初始化 jsp 解析器的代码:
context.addservletcontainerinitializer(new jasperinitializer(), null);
添加之后,再次启动main方法,浏览器输入127.0.0.1:8080得到的结果为tomcat的界面:
3.6 日志乱码
启动的日志中含有很多的乱码,虽然对程序整体并不影响,但是在之后查看日志时,还是影响比较大的,先看下日志乱码的情况:
- 解决方案:
修改vm options 内容,将环境设置为美国-英文,设置内容如下:
-duser.language=en -duser.region=us -dfile.encoding=utf-8
再次运行main方法,程序日志正常显示:
至此,我们已经将tomcat的源码导入到idea的工具中,也解决了一些问题,之后,我们将利用这份源码来分析tomcat的启动及运行原理。
blog:
- 简书:
- csdn: https://blog.csdn.net/zhiyouwu
- 开源中国:
- 掘金:
- 博客园:
- 微信公众号: 源码湾
- 微信: wzy1782357529 (欢迎沟通交流)
推荐阅读
-
vuex 源码分析(一) 使用方法和代码结构
-
kubernetes垃圾回收器GarbageCollector源码分析(一)
-
SpringBoot 源码解析 (六)----- Spring Boot的核心能力 - 内置Servlet容器源码分析(Tomcat)
-
Flink中watermark为什么选择最小一条(源码分析)
-
Tomcat源码分析 (九)----- HTTP请求处理过程(二)
-
Python的socket模块源码中的一些实现要点分析
-
Tomcat源码分析三:Tomcat启动加载过程(一)的源码解析
-
九、Spring之BeanFactory源码分析(一)
-
Mybaits 源码解析 (九)----- 全网最详细,没有之一:一级缓存和二级缓存源码分析
-
Tomcat源码分析 (二)----- Tomcat整体架构及组件