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:
- 简书: https://www.jianshu.com/u/91378a397ffe
- csdn: https://blog.csdn.net/ZhiyouWu
- 开源中国: https://my.oschina.net/u/3204088
- 掘金: https://juejin.im/user/5b5979efe51d451949094265
- 博客园: https://www.cnblogs.com/zhiyouwu/
- 微信公众号: 源码湾
- 微信: WZY1782357529 (欢迎沟通交流)
Tomcat源码分析一:编译Tomcat源码的更多相关文章
- php中foreach源码分析(编译原理)
php中foreach源码分析(编译原理) 一.总结 编译原理(lex and yacc)的知识 二.php中foreach源码分析 foreach是PHP中很常用的一个用作数组循环的控制语句.因为它 ...
- [Tomcat 源码分析系列] (二) : Tomcat 启动脚本-catalina.bat
概述 Tomcat 的三个最重要的启动脚本: startup.bat catalina.bat setclasspath.bat 上一篇咱们分析了 startup.bat 脚本 这一篇咱们来分析 ca ...
- Tomcat源码分析----eclipse中搭建源码环境
前提:JDK,至少1.7,ant,要设置ANT_HOME环境变量,需要再classpath中增加ant的lib目录,在path变量中增加ant的bin目录 1.官网下载tomcat源码包:apache ...
- Tomcat源码分析三:Tomcat启动加载过程(一)的源码解析
Tomcat启动加载过程(一)的源码解析 今天,我将分享用源码的方式讲解Tomcat启动的加载过程,关于Tomcat的架构请参阅<Tomcat源码分析二:先看看Tomcat的整体架构>一文 ...
- 精尽Spring Boot源码分析 - 内嵌Tomcat容器的实现
该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...
- 精尽Spring Boot源码分析 - 支持外部 Tomcat 容器的实现
该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...
- [转] jQuery源码分析-如何做jQuery源码分析
jQuery源码分析系列(持续更新) jQuery的源码有些晦涩难懂,本文分享一些我看源码的方法,每一个模块我基本按照这样的顺序去学习. 当我读到难度的书或者源码时,会和<如何阅读一本书> ...
- Redis源码分析:serverCron - redis源码笔记
[redis源码分析]http://blog.csdn.net/column/details/redis-source.html Redis源代码重要目录 dict.c:也是很重要的两个文件,主要 ...
- 序列化器中钩子函数源码分析、many关键字源码分析
局部钩子和全局钩子源码分析(2星) # 入口是 ser.is_valid(),是BaseSerializer的方法 # 最核心的代码 self._validated_data = self.run_v ...
- k8s client-go源码分析 informer源码分析(5)-Controller&Processor源码分析
client-go之Controller&Processor源码分析 1.controller与Processor概述 Controller Controller从DeltaFIFO中pop ...
随机推荐
- “玲珑杯”ACM比赛 Round #18 C -- 图论你先敲完模板(和题目一点关系都没有,dp)
题目链接:http://www.ifrog.cc/acm/problem/1146?contest=1020&no=2 题解:显然知道这是一道dp而且 dp[i]=min(dp[j]+2^(x ...
- Java IO写文件效率
写入方法: /** *1 按字节写入 FileOutputStream * * @param count 写入循环次数 * @param str 写入字符串 */ public void output ...
- Servlet跳转方式sendReDirect()和forward()
在web应用服务中,经常会面对不同SERVLET之间的跳转,目前我们可以通过以下两种方式实现: 1.RequestDispatcher.forward() 2.ServletResponse.send ...
- kubernetes部署jenkins(Docker in Docker)及认证
引言 Jenkins是一款开源 CI&CD 软件,用于自动化各种任务,包括构建.测试和部署软件. 本文将Jenkins的master与slave置于Pod中,部署在namespace:jenk ...
- Winform中设置DevExpress的RadioGroup的items从配置文件中加载
场景 DevExpress的RadioGroup的items选项如果是不确定的话,需要其从配置文件中加载. 实现 在项目目录下新建Config文件夹,文件夹下新建xml配置文件. <?xml v ...
- 【学习笔记】第三章 python3核心技术与实践--Jupyter Notebook
可能你已经知道,Python 在 14 年后的“崛起”,得益于机器学习和数学统计应用的兴起.那为什么 Python 如此适合数学统计和机器学习呢?作为“老司机”的我可以肯定地告诉你,Jupyter N ...
- oracle 常用脚本以及语句
oracle 常用脚本以及语句 一.oracle 安装10G 单机初始化环境: #!/bin/bash #关闭selinuxsed -i 's\SELINUX=enforcing\SELINUX=di ...
- Spring Boot + WebSocket 学习笔记
首先需要了解一下背景,什么是WebSocket以及为什么要用WebSocket. 在常见的Web应用中,客户端与服务器通信,都是通过HTTP协议进行通信,客户端一次请求,服务端一次响应.而WebSoc ...
- java处理emoji(转)
最近对接ios.安卓客户端,需要处理emoji等表情符号,网上总结: 1.过滤掉emoji表情符 2.修改数据库的编码格式等,让其支持存储emoji 以下分别对两种方案进行描述: 第一种:过滤掉emo ...
- 修改zabbix的端口号
1.前言 zabbix-server的默认端口号是10051.如果存在端口号冲突,需要更改端口号. 以下为更改端口号的步骤. 2.更改配置文件 通常用安装包,也就是yum方式部署的话,其默认的配置文 ...