从零构建tomcat环境
一、官网构建
1.1 下载
一般来说对于开源软件都有自己的官方网站,并且会附上使用文档以及一些特性和二次构建的方法,那么我们首先的话需要从官网或者tomcat上下载到我们需要的源码包。下载地址:官网、Github。


这里需要声明一下,我们是通过源码来进行编译的,所以我们需要下载src下的源码包,然后才能进行构建,而对于bin包下的是官网已经构建好的软件。
1.2 搭建ant环境
因为tomcat是JAVA语言编写的,所以在这里默认我们已经有了JAVA环境,然后我们直接进行安装ant。安装地址
因为在tomcat的官方网站上,明确的指出官方所支持的构建方式是ant构建,所以我们在这采用ant的方式来构建环境。
然后我们需要像安装JDK一样来进行配置环境变量,创建环境变量ANT_HOME=解压路径的根路径,再向PATH中添加%ANT_HOME%\bin,在控制台输入ant -version,观察到ANT的版本后就说明ant已经安装成功。

1.3 执行构建
我们首先需要配置一下构建的一些配置文件,先新建build.properties文件在主目录,并输入下面的几行配置。
#依赖下载的位置
base.path=D:\\Programe\\apache-tomcat-9.0.68-src\\dependency
#代理
proxy.host=127.0.0.1
proxy.port=7890
#是否使用代理
proxy.use=on
在执行构建的过程中,我们需要下载依赖包,所以会比较的缓慢。
我们直接在tomcat的主目录执行 ant 这个命令。然后就可以开启构建的流程了。

在看到上述的图片后就说明我们已经构建完成,到这里或许你会有疑问,为什么我们要构建一个tomcat,直接使用官方的不好吗。其实对于我们来说tomcat在使用的过程中更像是一个黑盒的容器,我们不知道它的内部具体实现,一般也只是在使用。构建tomcat能够帮助我们来二次开发和构建适合我们自己业务的软件,也可以让我们自己写的代码打入tomcat容器中。
上述的话便是官方方式推荐的构建tomcat,而我们的学习需要在编译器中把tomcat给跑起来,然后方便我们调试和学习,下来我们将进行IDEA版本的构建。
二、IDEA构建运行环境
2.1 构建环境
众所周知Tomcat实际上是一个JAVA的项目,而对于JAVA项目来说我们可以通过maven的方式来构建一个具有很方便的依赖管理方式的项目,就不再需要我们去下载依赖,而是直接通过maven仓库的方式进行管理,有效的规范了我们的依赖存放方式。
首先,我们需要将tomcat的源码通过IDEA打开,然后我们在根目录中进行新建一个pom.xml,并把此项目标记为maven项目。
<?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>Tomcat8.0</artifactId><name>Tomcat8.0</name><version>8.0</version><build><finalName>Tomcat8.0</finalName><!--声明JAVA源代码路径--><sourceDirectory>java</sourceDirectory><!--声明JAVA测试代码路径--><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.5.1</version><configuration><encoding>UTF-8</encoding><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build><dependencies><!--单元测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!--mock对象--><dependency><groupId>org.easymock</groupId><artifactId>easymock</artifactId><version>3.4</version></dependency><!--构建工具--><dependency><groupId>org.apache.ant</groupId><artifactId>ant</artifactId><version>1.10.14</version></dependency><!--解析WSDL文本的常用工具--><dependency><groupId>wsdl4j</groupId><artifactId>wsdl4j</artifactId><version>1.6.3</version></dependency><!--Java Web服务开发包(WSDP)的应用程序接口(API)--><dependency><groupId>javax.xml</groupId><artifactId>jaxrpc</artifactId><version>1.1</version></dependency><!--JavaTM 认可的Java 编译工具--><dependency><groupId>org.eclipse.jdt.core.compiler</groupId><artifactId>ecj</artifactId><version>4.6.1</version></dependency><dependency><groupId>biz.aQute.bnd</groupId><artifactId>biz.aQute.bndlib</artifactId><version>6.3.1</version></dependency></dependencies>
</project>

我们点击add as maven project,并刷新依赖关系,等待具体的依赖包下载完毕后就可以了。
2.2 运行
我们一般的启动方式是通过tomcat的bin目录下的start.bat或者是start.sh来进行启动,那么我们心中是否会有这样一个疑问?tomcat是否是有main函数的。这个回答是当然,对于JAVA程序来说main函数是方法执行的入口,如果没有入口函数,那么tomcat容器就不可能会进行启动,接下来我们就来通过启动脚本来探索一下tomcat启动的具体步骤。
setlocal
set "CURRENT_DIR=%cd%"
if not "%CATALINA_HOME%" == "" goto gotHome
set "CATALINA_HOME=%CURRENT_DIR%"
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
cd ..
set "CATALINA_HOME=%cd%"
cd "%CURRENT_DIR%"
:gotHome
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHomeset "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat"rem Check that target executable exists
if exist "%EXECUTABLE%" goto okExec
echo Cannot find "%EXECUTABLE%"
echo This file is needed to run this program
goto end
:okExecrem Get remaining unshifted command line arguments and save them in the
set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
:doneSetArgscall "%EXECUTABLE%" start %CMD_LINE_ARGS%:end
主要的就是找到catalina.bat,然后调用这个批处理命令,我们继续来看catalina.bat,这里就不进行贴出代码了,主要讲一下逻辑。
catalina.bat设置了几个环境变量,CATALINA_HOME和CATALINA_BASE,获取了安装的JAVA虚拟机的路径和参数,设置了日志文件的配置。
在这里面我们可以看到所指定的MAINCLASS,然后这个文件就是我们启动的main函数的所在类。


这样我们就知道了,在启动主类的时候我们要向虚拟机指定一些环境变量,不然的话导致main函数中的部分代码找不到资源文件,这里我们只指定必要的几个变量。
-Dcatalina.home=D:\apache-tomcat-9.0.68-src\apache-tomcat-9.0.68-src
-Dcatalina.base=D:\apache-tomcat-9.0.68-src\apache-tomcat-9.0.68-src
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djava.util.logging.config.file=D:\apache-tomcat-9.0.68-src\apache-tomcat-9.0.68-src\conf\logging.properties
我们来在IDEA里面新添加一个应用配置

选择主类为我们刚才找到的Bootstrap.java文件,并将上述的几个参数添加进虚拟机的运行时的参数列表。(这里请注意不是项目参数是虚拟机参数)
最后我们来进行启动项目。
这里可能会遇到编译错误,我们只需要将JDT的所有爆红的改为自己的版本即可,例如我是CompilerOptions.VERSION_1_8。

我们发现启动成功了,但是会有乱码的问题。

在我们自己安装的时候我们是通过配置文件解决的乱码,就是将所有的编码方式设置为GBK实现的,在这里呢我们来通过修改代码来实现。
修改org.apache.tomcat.util.res#getString(final String key, final Object… args)

try {value = new String(value.getBytes("ISO-8859-1"), "UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}
修改org.apache.jasper.compiler.Localizer#getMessage()
try {if (bundle != null) {errMsg = bundle.getString(errCode);}errMsg = new String(errMsg.getBytes("ISO-8859-1"), "UTF-8");} catch (MissingResourceException | UnsupportedEncodingException e) {}
然后我们再进行启动,就可以看到如下图的启动结果。

然后我们来进行访问我们我们熟悉的8080端口。

发生了空指针异常,这是因为我们没有添加jsp的解析类,导致了解析jsp时出现了异常,我们需要在ContextConfig.java中载入jsp的解析类。

最终
我们再进行启动就可以获得我们的主页了。
三、总结
今天我们通过了官网和编译器的方式构建了tomcat环境,之后我们可以很方便的对于我们自己的tomcat进行调试开发,然后通过官网的方式进行构建我们自己的二次开发的tomcat容器。
技术无难事,只是走的人少便成了难事,让我们共同学习,一起进步。
相关文章:
从零构建tomcat环境
一、官网构建 1.1 下载 一般来说对于开源软件都有自己的官方网站,并且会附上使用文档以及一些特性和二次构建的方法,那么我们首先的话需要从官网或者tomcat上下载到我们需要的源码包。下载地址:官网、Github。 这里需要声明一下ÿ…...
MySQL递归公用表表达式
😇作者介绍:一个有梦想、有理想、有目标的,且渴望能够学有所成的追梦人。 🎆学习格言:不读书的人,思想就会停止。——狄德罗 ⛪️个人主页:进入博主主页 🗼专栏系列:MySQL知识 &…...
深入 K8s 网络原理(一)- Flannel VXLAN 模式分析
1. 概述 这周集中聊下 K8s 的集群网络原理,我初步考虑分成3个方向: Pod-to-Pod 通信(同节点 or 跨节点),以 Flannel VXLAN 模式为例; Pod/External-to-Service 通信,以 iptables 实现为例&…...
fpga 8段4位数码管verilator模拟
8段4位数码管verilator模拟 seg.v module seg(input wire clk,input wire rst_n,output wire[7:0] SEG,output wire[3:0] SEL );reg[7:0] digit[0:15] {8h3f, 8h06, 8h5b, 8h4f, 8h66, 8h6d, 8h7d,8h07,8h7f,8h6f, 8h77, 8h7c, 8h39, 8h5e, 8h79, 8h71};reg[31:0] cnt 32…...
HttpURLConnection发送各种内容格式
通过java.net.HttpURLConnection类实现http post发送Content-Type为multipart/form-data的请求。 json处理使用com.fasterxml.jackson 图片压缩使用net.coobird.thumbnailator log使用org.slf4j 一些静态变量 private static final Charset charset StandardCharsets.UTF_8;…...
摇杆控制人物移动
摇杆控制人物移动 一、UI搭建二、3d模型搭建三、脚本JoyStickBar.csPlayerController.cs 工程在我资源里名字叫Joystickbar.unitypackage [连接](https://download.csdn.net/download/qq_42194657/12043019?spm1001.2014.3001.5503) 一、UI搭建 JoyStickBar是图片背景 JoySt…...
Jenkins自动化部署之后端
准备工作参考本人另外几篇Jenkins相关的文章 新建任务 添加参数配置 字符串参数:分支名称 多选框:项目名称(Extended Choice Parameter插件必备,插件安装参考我另外的文章) 这个分割规则自定义。只要根据Jenkins…...
Could not resolve com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.28.
1、首先进入阿里云maven仓库,在搜索栏输入无法下载的依赖名称,查询现有版本号,可以看到这里有2.9.34。 2、在build.gradle(Project)的buildscript闭包下替换为阿里云maven仓库: maven { url https://www.jitpack.io } maven { u…...
RK3588平台开发系列讲解(AI 篇)RKNN rknn_query函数详细说明
文章目录 一、查询 SDK 版本二、查询输入输出 tensor 个数三、查询输入 tensor 属性(用于通用 API 接口)四、查询输出 tensor 属性(用于通用 API 接口)五、查询模型推理的逐层耗时六、查询模型推理的总耗时七、查询模型的内存占用情况八、查询模型里用户自定义字符串九、查询原…...
15个主流设计灵感网站,激发你的创作灵感!
即时设计 即时设计是一种强大的云设计工具,已成为许多设计师、产品经理和开发人员的首选工具之一。即时设计用户可以使用内置的工具和功能快速创建和编辑设计,或与其他用户共享和合作。此外,即时设计还有一个丰富的资源社区,为用…...
Matlab:解非线性方程组
1、基于问题求解非线性方程组 例: xoptimvar(x,2); %将x定义为一个二元素优化变量 eq1exp(-exp(-(x(1)x(2))))x(2)*(1x(1)^2); %创建第一个方程作为优化等式表达式 eq2x(1)*cos(x(2))x(2)*sin(x(1))1/2; %创建第二个方程作为优化等式表达式 probe…...
面向 AI,重塑云基础设施、存储、芯片、Serverless……2023亚马逊云科技re:Invent中国行
一年一度亚马逊云科技重要的技术盛会 re:Invent 刚落下帷幕,2023 亚马逊云科技 re:Invent 中国行就将其中重要的信息与内容带给了中国市场和用户。作为全球的云计算巨头,今年亚马逊云科技可以说全面加码 AI,例如发布完整的端到端生成式 AI 技…...
【JDK新特性】JDK和Springboot各版本新特性介绍
目录 参考资料 以下是一些较新版本的JDK的主要新特性介绍: JDK 8: Lambda 表达式:引入了函数式编程的概念,使得代码更简洁、可读性更强。Stream API:提供了一种高效处理集合数据的方式,支持并行处理。默认…...
tomcat剖析:开篇
一、简介 本专栏为解析tomcat的专栏,用于一步步的从构建到执行,再到剖析tomcat的内部构造,然后再加上自己的理解,从0到1去认识我们日常开发中不可或缺的web容器,希望对之后的软件设计能够有所启示。 二、步骤 2.1构…...
华为路由器:DHCP配置
在大型企业网络中,会有大量的主机获取IP地址等网络参数。如果采用手工配置,则工作量大不好管理,若用户擅自更改网络参数,则容易导致IP冲突。 因此使用动态主机配置协议(DHCP)可以减少管理员的工作量&#x…...
(企业 / 公司项目)微服务OpenFeign怎么实现服务间调用?(含面试题)
Feign: 远程调用组件使用步骤,理解上面的图 后台系统中, 微服务和微服务之间的调用可以通过Feign组件来完成. Feign组件集成了Ribbon负载均衡策略(默认开启的, 使用轮询机制),Hystrix熔断器 (默认关闭的, 需要通过配置文件进行设置开启) 被调用的微服务…...
数据结构:图文详解 树与二叉树(树与二叉树的概念和性质,存储,遍历)
目录 一.树的概念 二.树中重要的概念 三.二叉树的概念 满二叉树 完全二叉树 四.二叉树的性质 五.二叉树的存储 六.二叉树的遍历 前序遍历 中序遍历 后序遍历 一.树的概念 树是一种非线性数据结构,它由节点和边组成。树的每个节点可以有零个或多个子节点…...
DM工作笔记-在windows下对DM7进行库还原恢复
提供了这些备份数据 在windows平台上,将这些备份数据还原到新库中。 首先实例得先停掉: 使用的软件console.exe: 重要步骤:①获取备份;②还原;③恢复 记住DMAP方式这个不要勾选,然后再获取备份…...
STM32软硬件CRC测速对比
硬件CRC配置 以及软硬件CRC速度对比 使用CUBEMX配置默认使用的是CRC32,从库中可以看出这一点 HAL库提供了以下两个计算函数 HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength); 这个函数用于在已有的CRC校验结果的基础上累积…...
第九部分 图论
目录 例 相关概念 握手定理 例1 图的度数列 例 无向图的连通性 无向图的连通度 例2 例3 有向图D如图所示,求 A, A2, A3, A4,并回答诸问题: 中间有几章这里没有写,感兴趣可以自己去学,组合数学跟高中差不多,…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
