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的首页,如果有问题,可以一起探讨。

相关推荐
jzshmyt3 小时前
大内存生产环境tomcat-jvm配置实践
java·jvm·tomcat
foo1st6 小时前
Tomcat Web应用(Ubuntu 18.04.6 LTS)部署笔记
ubuntu·tomcat
凯酱10 小时前
MyBatis-Plus分页插件的使用
java·tomcat·mybatis
佳腾_11 小时前
【Web应用服务器_Tomcat】一、Tomcat基础与核心功能详解
java·前端·中间件·tomcat·web应用服务器
爱的叹息15 小时前
mybatis-plus里的com.baomidou.mybatisplus.core.override.MybatisMapperProxy 类的详细解析
java·tomcat·mybatis
w23617346011 天前
Tomcat:从零理解Java Web应用的“心脏”
java·前端·tomcat
程序员阿鹏2 天前
实现SpringBoot底层机制【Tomcat启动分析+Spring容器初始化+Tomcat 如何关联 Spring容器】
java·spring boot·后端·spring·docker·tomcat·intellij-idea
Yang三少喜欢撸铁3 天前
【通过Docker快速部署Tomcat9.0】
linux·运维·服务器·docker·容器·tomcat
Craaaayon3 天前
JVM虚拟机-类加载器、双亲委派模型、类装载的执行过程
java·jvm·spring boot·后端·算法·java-ee·tomcat
玄尛9484 天前
论如何一句命令实现单tomcat多应用的部署
tomcat