Skip to main content

One post tagged with "tomcat"

View All Tags

tomcat 编译

· 4 min read

背景

了解tomcat生命周期,了解一个http的生命周期

步骤

  • 1 拉取tomcat 代码
git clone https://github.com/apache/tomcat

相关的编译后的安装目录在${tomcat.source}/build.propertiesfile 里面

  • 2 安装ant

我的是ubuntu所以直接通过包管理安装

sudo apt install ant

  • 3 修改复制build.properties 文件 这里面会有相关的属性,和下载代码相关的路径需要在这里配置
cp build.properties.default  build.properties


我们需要将调试符号编译时生成,如果是一个java程序,则是javac -g , 也就是在编译的时候添加到javac 中. 在tomcat的源代码中的build.xml 中很容易看到compile.debug 这个环境变量

<javac srcdir="java" destdir="${tomcat.classes}"
debug="${compile.debug}" <--! 这里会有compile.debug 环境变量 ->
deprecation="${compile.deprecation}"
release="${compile.release}"
encoding="ISO-8859-1"
includeAntRuntime="true" >
<!-- Uncomment this to show unchecked warnings:
<compilerarg value="-Xlint:unchecked"/>

那么这个环境变量是在哪里控制的呢? 打开 build.properties ,就能看到,所以默认下载下来的tomcat 就是开了-g 选项的,不需要修改

# ----- Build control flags -----
compile.debug=true
  • 4 执行构建命令ant
ant

编译好的相关代码会在 , source_code 就是你的源代码

{source_code}/output/build/bin

切换目录到{source_code}/output/build/bin

./startup.sh 
Using CATALINA_BASE: /home/dai/tomcat/output/build
Using CATALINA_HOME: /home/dai/tomcat/output/build
Using CATALINA_TMPDIR: /home/dai/tomcat/output/build/temp
Using JRE_HOME: /usr
Using CLASSPATH: /home/dai/tomcat/output/build/bin/bootstrap.jar:/home/dai/tomcat/output/build/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.

查看tomcat 的命令 , 就是以下内容:

ps aux | grep tomcat


/usr/bin/java -Djava.util.logging.config.file=/home/dai/tomcat/output/build/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED -classpath /home/dai/tomcat/output/build/bin/bootstrap.jar:/home/dai/tomcat/output/build/bin/tomcat-juli.jar -Dcatalina.base=/home/dai/tomcat/output/build -Dcatalina.home=/home/dai/tomcat/output/build -Djava.io.tmpdir=/home/dai/tomcat/output/build/temp org.apache.catalina.startup.Bootstrap start


请求tomcat

在浏览器输入 http://127.0.0.1:8080/

debug tomcat

断点到main函数

在上面步骤用ps aux | grep "tomcat" 获取执行的命令 , 然后在前面/usr/bin/java 紧接着的地方加上参数-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000 ,让程序断点在main函数

参数说明:

  • suspend 代表是否暂停
  • address: 指定地址 , 也可以只指定端口,我这里是8000 端口
  • -agentlib:jdwp=transport 协议 ,一般本地用socket 通讯 , 也可以共享内存什么的 。 我这里是dt_socket
/usr/bin/java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000   -Djava.util.logging.config.file=/home/dai/tomcat/output/build/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED -classpath /home/dai/tomcat/output/build/bin/bootstrap.jar:/home/dai/tomcat/output/build/bin/tomcat-juli.jar -Dcatalina.base=/home/dai/tomcat/output/build -Dcatalina.home=/home/dai/tomcat/output/build -Djava.io.tmpdir=/home/dai/tomcat/output/build/temp org.apache.catalina.startup.Bootstrap start

jdb 开启调试

jdb  -attach  8000 -sourcepath /home/dai/tomcat/java/

### 在 org.apache.catalina.startup.Bootstrap.main 打断点
main[1] stop in org.apache.catalina.startup.Bootstrap.main
Deferring breakpoint org.apache.catalina.startup.Bootstrap.main.
It will be set after the class is loaded.
#### 使用run开始执行
main[1] run

使用list 列出代码 然后就会断点到main 函数

Breakpoint hit: "thread=main", org.apache.catalina.startup.Bootstrap.main(), line=442 bci=0
442 synchronized (daemonLock) {

main[1] list
438 * @param args Command line arguments to be processed
439 */
440 public static void main(String args[]) {
441
442 => synchronized (daemonLock) {
443 if (daemon == null) {
444 // Don't set daemon until init() has completed
445 Bootstrap bootstrap = new Bootstrap();
446 try {
447 bootstrap.init();
main[1]

servelet 请求路径

http-nio-8080-exec-1[1] where
[1] HelloWorldExample.doGet (HelloWorldExample.java:41)
[2] jakarta.servlet.http.HttpServlet.service (HttpServlet.java:705)
[3] jakarta.servlet.http.HttpServlet.service (HttpServlet.java:814)
[4] org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:223)
[5] org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:158)
[6] org.apache.tomcat.websocket.server.WsFilter.doFilter (WsFilter.java:53)
[7] org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:185)
[8] org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:158)
[9] org.apache.catalina.filters.HttpHeaderSecurityFilter.doFilter (HttpHeaderSecurityFilter.java:126)
[10] org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:185)
[11] org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:158)
[12] org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:177)
[13] org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:97)
[14] org.apache.catalina.authenticator.AuthenticatorBase.invoke (AuthenticatorBase.java:542)
[15] org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:119)
[16] org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:92)
[17] org.apache.catalina.valves.AbstractAccessLogValve.invoke (AbstractAccessLogValve.java:690)
[18] org.apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java:78)
[19] org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:357)
[20] org.apache.coyote.http11.Http11Processor.service (Http11Processor.java:400)
[21] org.apache.coyote.AbstractProcessorLight.process (AbstractProcessorLight.java:65)
[22] org.apache.coyote.AbstractProtocol$ConnectionHandler.process (AbstractProtocol.java:859)
[23] org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun (NioEndpoint.java:1,734)
[24] org.apache.tomcat.util.net.SocketProcessorBase.run (SocketProcessorBase.java:52)
[25] org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1,191)
[26] org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:659)
[27] org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run (TaskThread.java:61)
[28] java.lang.Thread.run (Thread.java:833)

相关阅读