tomcat源码调试之环境搭建

准备工作

调试工具:
idea 2023.3.2 + maven-3.6.3 + jdk 1.8

源码获取方式:

tomcat源码地址:github.com/apache/tomc...

clone:github.com/apache/tomc...

考虑到很多国内网络环境原因,直接在gitee上新建仓库,导入即可,gitee操作如下

导入之后:

点击确定即可,这样源码就clone到gitee上了,我们在gitee上新建一个分支,以9.0.x分支为基准,建一个9.0x-study,接下来就是clone你gitee的分支,我相信大家都是clone的一把老手了,就忽略步骤了。

正式开始

接下来就开始我们的环境搭建,idea打开tomcat源码,切换到我们的目标分支上(9.0x-study)分支上,由于tomcat是用ant进行管理,我没有使用ant,我使用的是maven,原理都差不多,都是下载依赖jar包, 在tomcat目录下,新建一个pom.xml文件,这里我也是搜了一下别人的方案,有坑,经过排查之后的文件内容如下:

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>tomcat</artifactId>
  <name>tomcat</name>
  <version>9.0</version>
  <description>9.0.x分支有效,其他分支请自己尝试解决</description>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>ant</groupId>
      <artifactId>ant</artifactId>
      <version>1.6.5</version>
    </dependency>
    <dependency>
      <groupId>org.easymock</groupId>
      <artifactId>easymock</artifactId>
      <version>4.3</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.26</version>
    </dependency>
    <dependency>
      <groupId>biz.aQute.bnd</groupId>
      <artifactId>biz.aQute.bndlib</artifactId>
      <version>5.2.0</version>
      <scope>provided</scope>
    </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.core.compiler</groupId>
     <artifactId>ecj</artifactId>
    <version>4.6.1</version>
    </dependency> -->

   <!--此配置项才是正确的,上面那个包迁移了,有很多代码里配置项都找不到会报错-->
    <dependency>
      <groupId>org.eclipse.jdt</groupId>
      <artifactId>ecj</artifactId>
      <version>3.26.0</version>
    </dependency>


  </dependencies>

  <build>
    <finalName>tomcat</finalName>
    <sourceDirectory>java</sourceDirectory>
    <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.5.1</version>
        <configuration>
          <encoding>UTF-8</encoding>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.6</version>
      </plugin>
    </plugins>
  </build>
</project>

然后直接加载pom文件,开始下载依赖。

开始启动

首先我们需要找到tomcat的启动类,那该怎么找到呢? 回想我们启动tomcat的过程,以liunx为例,首先我们会去tomcat的bin目录下,执行startup.sh这个脚本,那么我们就顺着这个脚本往下看,一层层的去找到最后的方法,毕竟咱们java的启动入口是main方法,对吧!

在脚本里又去执行了catalina.sh,那么我们继续往下看catalina脚本,在脚本里,判断参数啥的,还有就是一些设置之类的,关键的在后,不管走什么分支,都会执行如下一行代码:

脚本具体的内容因为本人水平有限,不展开细说,主要关键的一句代码

bash 复制代码
org.apache.catalina.startup.Bootstrap "$@" start

这是主启动类,我们去看看对应的源码,里面有一个main方法,重要的事情说三遍,main方法、main方法、main方法.

我们java启动的函数入口,终于追到这个方法了,看情况是执行catalina.sh的时候,脚本传了一个参数:start,对应的源码里判断args的参数是不是start,那么我们启动的时候,肯定要给main方法也传入一个start参数,这样才能对应好里面的分支条件判断,执行分支的代码吧,当然也有别的参数要传入如下参数需要传:

ini 复制代码
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djava.util.logging.config.file=F:\workspace\java\tomcat\conf\logging.properties

怎么传入进去呢? 我们需要打开idea的启动选项如下所示:

编辑配置

添加一个应用程序

解释如下: 1、选择一个jdk版本,我这里用的是8,可以看看官网对应的版本就可以,而且idea可以管理多个Jdk版本,很方便,小伙伴搜一下就可以,这里不做过多的解释 2、填写我们的参数,直接复制就可以,里面的logging.properties 路径要根据你具体tomcat路径填写要绝对路径哈 3、填写我们的启动类,直接填写 org.apache.catalina.startup.Bootstrap 就可以,复制的时候注意空格 4、填写启动的参数start。 温馨提示,有很多小伙伴更新到最新的版本之后,只有一处填写启动参数的地方,可以打开选项,打开添加虚拟机选项,就会多一行

至此可以打开debug开启你的调试之路了,可以跟上源代码流程,以下是我遇到的问题,启动乱码,直接去 org.apache.tomcat.util.res.StringManager#getString 方法里面(注意哦,有重载),关注一个参数的方法 ,在最后返回str的时候,直接转码一下,因为默认的编码是ISO-8850-1,可能在启动参数的时候,加上编码字符集也可以,不过我没加

javascript 复制代码
if(str!=null){
    try {
            str = new String(str.getBytes("ISO-8859-1"), "UTF-8");
    }catch (Exception exception){

    }
}

如果解析jsp报错,可以尝试一下方法打开org.apache.catalina.startup.ContextConfig#configureStart 方法中,添加一行代码,是为了解析jsp的,默认是没有需要自己加

代码如下:

csharp 复制代码
context.addServletContainerInitializer(new JasperInitializer(), null);

至此,我本地启动已经可以了,而且直接访问127.0.0.1:8080 可以直接出现tomcat的首页,如果有问题,可以一起探讨。

相关推荐
巨大八爪鱼4 小时前
XP系统下用mod_jk 1.2.40整合apache2.2.16和tomcat 6.0.29,让apache可以同时访问php和jsp页面
java·tomcat·apache·mod_jk
程序员小海绵【vincewm】15 小时前
【设计模式】结合Tomcat源码,分析外观模式/门面模式的特性和应用场景
设计模式·tomcat·源码·外观模式·1024程序员节·门面模式
.生产的驴16 小时前
SpringBootCloud 服务注册中心Nacos对服务进行管理
java·spring boot·spring·spring cloud·tomcat·rabbitmq·java-rabbitmq
XiaoLiuLB19 小时前
Docker 指令详解:全面掌握容器化管理工具
java·tomcat·nio
程序员小羊!2 天前
HTTP&Tomcat&Servle之HTTP详解
网络协议·http·tomcat
Ada大侦探2 天前
新手小白学习docker第六弹------Docker常规安装(安装tomcat、mysql、redis)
mysql·docker·tomcat
xybm16052 天前
MTSET可溶于DMSO、DMF、THF等有机溶剂,并在水中有轻微的溶解性,91774-25-3
java·spring·eclipse·tomcat·1024程序员节
旧故新长2 天前
解决MySQL中整型字段条件判断禁用不生效的问题
数据库·oracle·tomcat
zhangxueyi2 天前
Tomcat与Nginx之全面比较
linux·运维·服务器·nginx·tomcat
乌啼霜满天2492 天前
tomcat与servlet版本对应关系
java·servlet·tomcat