tomcat源码学习记录

tomcat 学习记录

  • tomcat 编译
    • ant 下载
    • 编译
    • 运行
  • 源码Debug
    • 运行 Bootstrap
    • 运行Tomcat
    • 查看状态
  • pom.xml
  • 测试
    • EmbeddedTomcat
  • 参考
    • 书籍
    • 博客

tomcat 编译

下载 tomcat 10 源码,解压然后idea导入
包存放的默认位置如下:base.path=${user.home}/tomcat-build-libs
同时在项目的 tomcat/res/ide-support/idea/tomcat.iml 文件中提供了jar的依赖配置方式, 可以覆盖 .idea 配置,但对于 社区版有些插件是无法安装的,就从 ${user.home}/tomcat-build-libs 手动导入 jar 包

参考

  • Tomcat 源码阅读与调试环境搭建 - 基于Idea和Tomcat 8.5

ant 下载

ant 二进制包下载 后添加环境变量 %ANT_HOME%\bin,idea2023 会自动识别, 或者打开 help-> action 搜索 ant

编译

  • 根路径下 build.properties.default,将其复制为 build.properties
  • 打开ant侧边栏,点击“+”,选择tomcat下的build.xml文件
  • 由于 windows默认编码集为GBK,由于使用startup.bat启动tomcat时,它会读取catalina.bat的代码并打开一个新窗口运行。打开的cmd默认编码可能不是utf-8,与系统编码不一致,所以导致乱码
    • 通过修改注册表
    • 修改 conf/logging.properties 日志编码为GBK
  • 在项目结构设置里,添加 JDK,同时设置 java 目录为源代码目录

点击 ant 窗口的运行按钮

运行

在输出目录下的 build/bin 运行 startup.bat

在浏览器 http://localhost:8080/

在这里插入图片描述

源码Debug

导入 ant 依赖
在这里插入图片描述
导入 ${user.home}/tomcat-build-libs 下的依赖
在这里插入图片描述

针对 java lang ClassNotFoundException listeners ContextListener 错误,是由于在idea的maven项目中要将java文件编译,加载进内存需要将文件夹设置为Sources Root

在这里插入图片描述

运行 Bootstrap

java/org/apache/catalina/startup/Bootstrap.java 中,自己调试运行

在这里插入图片描述

运行Tomcat

代码路径 java/org/apache/catalina/startup/Tomcat.java

public static void main(String[] args) throws Exception {// Process some command line parametersString[] catalinaArguments = null;for (int i = 0; i < args.length; i++) {if (args[i].equals("--no-jmx")) {Registry.disableRegistry();} else if (args[i].equals("--catalina")) {// This was already processed before// Skip the rest of the arguments as they are for CatalinaArrayList<String> result = new ArrayList<>();for (int j = i + 1; j < args.length; j++) {result.add(args[j]);}catalinaArguments = result.toArray(new String[0]);break;}}SecurityClassLoad.securityClassLoad(Thread.currentThread().getContextClassLoader());Tomcat tomcat = new Tomcat();// Create a Catalina instance and let it parse the configuration files// It will also set a shutdown hook to stop the Server when needed// Use the default configuration sourcetomcat.init(null, catalinaArguments);boolean await = false;String path = "";// Process command line parametersfor (int i = 0; i < args.length; i++) {if (args[i].equals("--war")) {if (++i >= args.length) {throw new IllegalArgumentException(sm.getString("tomcat.invalidCommandLine", args[i - 1]));}File war = new File(args[i]);tomcat.addWebapp(path, war.getAbsolutePath());} else if (args[i].equals("--path")) {if (++i >= args.length) {throw new IllegalArgumentException(sm.getString("tomcat.invalidCommandLine", args[i - 1]));}path = args[i];} else if (args[i].equals("--await")) {await = true;} else if (args[i].equals("--no-jmx")) {// This was already processed before} else if (args[i].equals("--catalina")) {// This was already processed before// Skip the rest of the arguments as they are for Catalinabreak;} else {throw new IllegalArgumentException(sm.getString("tomcat.invalidCommandLine", args[i]));}}tomcat.start();// Ideally the utility threads are non daemonif (await) {tomcat.getServer().await();}
}

查看状态

conf/tomcat-users.xml 添加用户

 <user username="admin" password="admin" roles="manager-gui,admin-gui,tomcat"/>

在这里插入图片描述

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--~ Licensed to the Apache Software Foundation (ASF) under one or more~ contributor license agreements.  See the NOTICE file distributed with~ this work for additional information regarding copyright ownership.~ The ASF licenses this file to You under the Apache License, Version 2.0~ (the "License"); you may not use this file except in compliance with~ the License.  You may obtain a copy of the License at~~      http://www.apache.org/licenses/LICENSE-2.0~~ Unless required by applicable law or agreed to in writing, software~ distributed under the License is distributed on an "AS IS" BASIS,~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.~ See the License for the specific language governing permissions and~ limitations under the License.--><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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.apache.tomcat</groupId><artifactId>apache-tomcat-10.1.16-src</artifactId><name>Tomcat</name><version>10.1.16</version><build><!--指定源目录--><finalName>apache-tomcat-10.1.16-src</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>11</source><target>11</target></configuration></plugin></plugins></build><!--tomcat 依赖的基础包--><dependencies><dependency><groupId>geronimo-spec</groupId><artifactId>geronimo-spec-jaxrpc</artifactId><version>1.1-rc4</version></dependency><dependency><groupId>wsdl4j</groupId><artifactId>wsdl4j</artifactId><version>1.6.3</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><dependency><groupId>org.hamcrest</groupId><artifactId>hamcrest</artifactId><version>2.2</version><scope>test</scope></dependency><dependency><groupId>org.easymock</groupId><artifactId>easymock</artifactId><version>4.3</version></dependency><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version></dependency><dependency><groupId>org.objenesis</groupId><artifactId>objenesis</artifactId><version>3.3</version></dependency><dependency><groupId>com.unboundid</groupId><artifactId>unboundid-ldapsdk</artifactId><version>6.0.10</version></dependency><dependency><groupId>com.puppycrawl.tools</groupId><artifactId>checkstyle</artifactId><version>10.12.4</version></dependency><dependency><groupId>org.jacoco</groupId><artifactId>org.jacoco.agent</artifactId><version>0.8.11</version></dependency><dependency><groupId>com.github.spotbugs</groupId><artifactId>spotbugs</artifactId><version>4.8.0</version><type>pom</type></dependency><dependency><groupId>biz.aQute.bnd</groupId><artifactId>biz.aQute.bndlib</artifactId><version>7.0.0</version></dependency><dependency><groupId>org.apache.tomcat</groupId><artifactId>jakartaee-migration</artifactId><version>1.0.7</version></dependency><dependency><groupId>net.jsign</groupId><artifactId>jsign-core</artifactId><version>5.0</version></dependency><dependency><groupId>org.apache.derby</groupId><artifactId>derby</artifactId><version>10.16.1.1</version><scope>test</scope></dependency><dependency><groupId>ant</groupId><artifactId>ant</artifactId><version>1.7.0</version></dependency><dependency><groupId>org.eclipse.jdt</groupId><artifactId>ecj</artifactId><version>3.36.0</version></dependency><dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-juli</artifactId><version>11.0.0-M14</version></dependency></dependencies>
</project>

测试

EmbeddedTomcat

public class EmbeddedTomcat {private static void resetLogging() {final String loggingConfig = "handlers = java.util.logging.ConsoleHandler\n" +".handlers = java.util.logging.ConsoleHandler\n" +"java.util.logging.ConsoleHandler.level = FINE\n" +"java.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter\n" +"java.util.logging.ConsoleHandler.encoding = UTF-8\n";try {InputStream is = new ByteArrayInputStream(loggingConfig.getBytes(StandardCharsets.UTF_8));LogManager.getLogManager().readConfiguration(is);LogFactory.getLog(EmbeddedTomcat.class).info("Logger configured to System.out");} catch (SecurityException | IOException e) {// Ignore, the VM default will be used}}public static void main(String... args) throws Exception {Registry.disableRegistry();Tomcat tomcat = new Tomcat();resetLogging();tomcat.setPort(8080);Connector connector = tomcat.getConnector();connector.setProperty("bindOnInit", "false");// No file system docBase requiredContext ctx = tomcat.addContext("", null);skipTldsForResourceJars(ctx);CounterServlet counterServlet = new CounterServlet();Tomcat.addServlet(ctx, "counterServlet", counterServlet);ctx.addServletMappingDecoded("/", "counterServlet");//ctx.addApplicationListener(new WsContextListener());tomcat.start();Thread.sleep(60*1000);}public static void skipTldsForResourceJars(Context context) {StandardJarScanner scanner = (StandardJarScanner) context.getJarScanner();StandardJarScanFilter filter = (StandardJarScanFilter) scanner.getJarScanFilter();filter.setTldSkip(filter.getTldSkip() + ",resources*.jar");}private static class CounterServlet extends HttpServlet {private static final long serialVersionUID = 1L;private AtomicInteger callCount = new AtomicInteger(0);@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {req.getSession(true);resp.setContentType("text/plain");resp.getWriter().print("OK: " + req.getRequestURL() + "[" + callCount.incrementAndGet()+ "]");}}
}

参考

  • Apache Tomcat

书籍

  • 深入剖析 Tomcat
  • Tomcat 架构解析

博客

  • Tomcat源码详解知识体系详解
  • tomcat源码分析
  • Tomcat 分析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/214383.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024 年顶级的 Android 系统修复软件与方法

您是否正在寻找可以修复 PC 上 Android 操作系统的工具&#xff1f;这是我们精选的最好的 Android 系统修复软件&#xff01; Android 是世界著名的智能手机操作系统。全世界有数百万人使用这个操作系统&#xff0c;这使得它安全可靠。然而&#xff0c;这仍然不能使它完美无缺…

数据分析基础之《matplotlib(4)—柱状图》

一、柱状图绘制 1、柱状图要素 有类别 2、需求&#xff1a;对比每部电影的票房收入 电影数据如下图所示&#xff1a; 3、matplotlib.pyplot.bar(x, height, width0.8, bottomNone, *, aligncenter, dataNone, **kwargs) 说明&#xff1a; x&#xff1a;有几个类别 height&am…

vscode 编译运行c++ 记录

一、打开文件夹&#xff0c;新建或打开一个cpp文件 二、ctrl shift p 进入 c/c配置 进行 IntelliSense 配置。主要是选择编译器、 c标准&#xff0c; 设置头文件路径等&#xff0c;配置好后会生成 c_cpp_properties.json&#xff1b; 二、编译运行&#xff1a; 1、选中ma…

vue 实现返回顶部功能-指定盒子滚动区域

vue 实现返回顶部功能-指定盒子滚动区域 html代码css代码返回顶部显示/隐藏返回标志 html代码 <a-icontype"vertical-align-top"class"top"name"back-top"click"backTop"v-if"btnFlag"/>css代码 .top {height: 35px;…

MA营销自动化如何助力商家实现精准营销?

惟客数据 MAP 是一个跨渠道和设备的自动化营销平台&#xff0c;允许接触点编排个性化旅程&#xff0c;通过短信、社交推送等方式为您的客户创建无缝的个性化体验&#xff0c;加强客户关系并赢得忠诚度。可与惟客数据CDP 产品无缝配合使用&#xff0c;通过数据驱动做出更实时&am…

Kotlin Flow 操作符

前言 Kotlin 拥有函数式编程的能力&#xff0c;使用Kotlin开发&#xff0c;可以简化开发代码&#xff0c;层次清晰&#xff0c;利于阅读。 然而Kotlin拥有操作符很多&#xff0c;其中就包括了flow。Kotlin Flow 如此受欢迎大部分归功于其丰富、简洁的操作符&#xff0c;巧妙使…

当使用RSA加密,从手机前端到服务器后端的请求数据存在+

将转成了空格&#xff0c;导致解密出错 将空格转成了

字节开源的netPoll底层LinkBuffer设计与实现

字节开源的netPoll底层LinkBuffer设计与实现 为什么需要LinkBuffer介绍设计思路数据结构LinkBufferNodeAPI LinkBuffer读 API写 APIbook / bookAck api 小结 本文基于字节开源的NetPoll版本进行讲解&#xff0c;对应官方文档链接为: Netpoll对应官方文档链接 netPoll底层有一个…

Google Bard vs. ChatGPT 4.0:文献检索、文献推荐功能对比

在这篇博客中&#xff0c;我们将探讨和比较四个不同的人工智能模型——ChatGPT 3.5、ChatGPT 4.0、ChatGPT 4.0插件和Google Bard。我们将通过三个问题的测试结果来评估它们在处理特定任务时的效能和响应速度。 导航 问题 1: 统计自Vehicle Routing Problem (VRP)第一篇文章发…

【C++】简单工厂模式

2023年12月6日&#xff0c;周三下午 今天又学习了一次简单工厂模式 每多学习一次&#xff0c;都会加深对设计模式的理解 目录 什么是简单工厂模式简单工厂模式的优缺点举例说明 什么是简单工厂模式 简单工厂模式&#xff08;Simple Factory Pattern&#xff09;是一种创建型…

SSD基础架构与NAND IO并发问题探讨

在我们的日常生活中&#xff0c;我们经常会遇到一些“快如闪电”的事物&#xff1a;比如那场突如其来的雨、那个突然出现在你眼前的前任、还有就是今天我们要聊的——固态硬盘&#xff08;SSD&#xff09;。 如果你是一个技术宅&#xff0c;或者对速度有着近乎偏执的追求&…

laravel的ORM 对象关系映射

Laravel 中的 ORM&#xff08;Eloquent ORM&#xff09;是 Laravel 框架内置的一种对象关系映射系统&#xff0c;用于在 PHP 应用中与数据库进行交互。Eloquent 提供了一种优雅而直观的语法&#xff0c;使得开发者可以使用面向对象的方式进行数据库查询和操作。 定义模型&…

c语言一维数组总结详解

目录 介绍&#xff1a; 一维整型数组&#xff1a; 声明&#xff1a; 初始化&#xff1a; 打印输出&#xff1a; 输出结果&#xff1a; 浮点型数组&#xff1a; 代码&#xff1a; 运行结果&#xff1a; 补充&#xff1a; 一维字符数组&#xff1a; 字符数组声明及初始…

运维05:自动化

人工运维时代 运维人员早期需要维护众多的机器&#xff0c;因此需要执行很多重复的劳动&#xff0c;很多机器需要同时部署相同的服务或者是执行相同的命令&#xff0c;还得反复地登录不同的机器&#xff0c;执行重复的动作 自动化运维时代 早期运维人员会结合ssh免密登录&…

Linux权限详解

Linux权限 文章目录 Linux权限一、root账号与普通账号二、Linux权限管理三、权限权值表示方法四、文件访问权限的设置方法五、粘滞位六、权限总结 前言&#xff1a; 我们在学习Linux的时候&#xff0c;我们知道在Linux下一切皆文件&#xff0c;而不同的文件对于不同的用户有不同…

回味童年经典游戏的项目

目录 1.超级玛丽2.坦克大战3.吃豆人游戏4.贪吃蛇游戏 1.超级玛丽 项目地址&#xff1a;超级马里奥游戏源码 在线试玩网址在资源描述中 在线试玩&#xff1a;http://martindrapeau.github.io/backbone-game-engine/super-mario-bros/index.html 主要语言&#xff1a;JavaScript…

《ReactJS实践入门》:引领JavaScript前端开发的革新之旅

在当今的软件开发世界中&#xff0c;ReactJS无疑是最为引人注目的JavaScript库之一。对于初学者来说&#xff0c;如何深入理解并掌握这一强大的前端工具&#xff0c;进而应用到实际开发中&#xff0c;一直是他们所面临的问题。而《ReactJS实践入门》一书&#xff0c;正是为了解…

使用Caliper对Fabric地basic链码进行性能测试

如果你需要对fabric网络中地合约进行吞吐量、延迟等性能进行评估&#xff0c;可以使用Caliper来实现&#xff0c;会返回给你一份网页版的直观测试报告。下面是对test-network网络地basic链码地测试过程。 目录 1. 建立caliper-workspace文件夹2. 安装npm等3. calipe安装4. 创建…

type property can‘t be changed 报错问题解决

问题 在使用 jQuery的 attr 方法对 input 输入框的 type 类型进行修改的时候报 type property can’t be changed 这个错误。 $psd.attr(type,text)原因 jQuery 的版本问题&#xff0c;当前使用的 jQuery 版本不允许修改 input 的 type属性所以报错。 解决方法 换原生 js …

使用消息队列遇到的问题—kafka

目录 1 分区2 消费者3 Kafka 如何保证消息的消费顺序&#xff1f;3.1 方案一3.2 方案二 4 消息积压 在项目中使用kafka作为消息队列&#xff0c;核心工作是创建生产者—包装数据&#xff1b;创建消费者----包装数据。 欠缺一些思考&#xff0c;特此梳理项目中使用kafka遇到的一…