1. 首页
  2. 技术知识

Idea中tomcat启动源码调试进入到tomcat内部进行调试的方法

使用idea开发工具调试代码的时候,如果是java的web项目,使用的是tomcat作为web容器,打断点debug调试跟踪,当跟踪到org.apache.catalina包下的时候,则无法进入,这是因为idea运行的tomcat是通过插件的方式集成的,tomcat里面的lib包不再项目的依赖路径中,所以不能跟踪进去

首先在自己项目中被tomcat回调的接口实现类中,标记一个断点信息,通过idea启动web项目,当出现如图所示的断点信息的时候,因为断点位置标记的是tomcat回调的接口类,所以按照调用堆栈网上则是tomcat内部代码,但此时双击org.apache.catalina包下面的类名,是没有任何反应的,因为我们还没有将tomcat对应的依赖文件添加到classpath下面


添加依赖

<dependency>

<groupId>org.apache.tomcat</groupId>

<artifactId>tomcat-catalina</artifactId>

<version>8.5.55</version>

<scope>provided</scope>

</dependency>因为运行时使用的是tomcat的lib目录下面的jar文件,所以此处的scope使用
provided方式


下面就可以进入到tomcat源码调试了

tomcat启动日志是怎么执行打出来的?

03-Jun-2022 10:31:30.929 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server.服务器版本: Apache Tomcat/8.5.55

03-Jun-2022 10:31:30.938 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 服务器构建:    May 5 2022 22:10:54 UTC

03-Jun-2022 10:31:30.938 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 服务器版本号(:   8.5.55.0

03-Jun-2022 10:31:30.938 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 操作系统名称:   Windows 10

03-Jun-2022 10:31:30.938 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log OS.版本:      10.0

03-Jun-2022 10:31:30.938 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 架构:       amd64

03-Jun-2022 10:31:30.939 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java 环境变量:   C:\Program Files\Java\jdk1.8.0_212\jre

03-Jun-2022 10:31:30.939 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java虚拟机版本:  1.8.0_212-b10

03-Jun-2022 10:31:30.939 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log JVM.供应商:    Oracle Corporation

03-Jun-2022 10:31:30.939 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:   C:\Users\Administrator\.IntelliJIdea2022.3\system\tomcat\Unnamed_spring-shiro-training

03-Jun-2022 10:31:30.939 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:   D:\tomcat8.5.55\apache-tomcat-8.5.55

通过定位到 VersionLoggerListener 日志可以查看到

private void log() {

log.info(sm.getString(“versionLoggerListener.serverInfo.server.version”,

  ServerInfo.getServerInfo()));

log.info(sm.getString(“versionLoggerListener.serverInfo.server.built”,

  ServerInfo.getServerBuilt()));

log.info(sm.getString(“versionLoggerListener.serverInfo.server.number”,

  ServerInfo.getServerNumber()));

log.info(sm.getString(“versionLoggerListener.os.name”,

  System.getProperty(“os.name”)));

log.info(sm.getString(“versionLoggerListener.os.version”,

  System.getProperty(“os.version”)));

log.info(sm.getString(“versionLoggerListener.os.arch”,

  System.getProperty(“os.arch”)));

log.info(sm.getString(“versionLoggerListener.java.home”,

  System.getProperty(“java.home”)));

log.info(sm.getString(“versionLoggerListener.vm.version”,

  System.getProperty(“java.runtime.version”)));

log.info(sm.getString(“versionLoggerListener.vm.vendor”,

  System.getProperty(“java.vm.vendor”)));

log.info(sm.getString(“versionLoggerListener.catalina.base”,

  System.getProperty(“catalina.base”)));

log.info(sm.getString(“versionLoggerListener.catalina.home”,

  System.getProperty(“catalina.home”)));

if (logArgs) {

List<String> args = ManagementFactory.getRuntimeMXBean().getInputArguments();

for (String arg : args) {

  log.info(sm.getString(“versionLoggerListener.arg”, arg));

}

}

if (logEnv) {

SortedMap<String, String> sortedMap = new TreeMap<>(System.getenv());

for (Map.Entry<String, String> e : sortedMap.entrySet()) {

  log.info(sm.getString(“versionLoggerListener.env”, e.getKey(), e.getValue()));

}

}

if (logProps) {

SortedMap<String, String> sortedMap = new TreeMap<>();

for (Map.Entry<Object, Object> e : System.getProperties().entrySet()) {

  sortedMap.put(String.valueOf(e.getKey()), String.valueOf(e.getValue()));

}

for (Map.Entry<String, String> e : sortedMap.entrySet()) {

  log.info(sm.getString(“versionLoggerListener.prop”, e.getKey(), e.getValue()));

}

}

}发现是通过键值对的方式获取的,
再通过字符串全局搜索发现

但是匹配的是英文,
那么中文是怎么打出来的呢?

最后通过调试发现找的是这个

类似上面的东西,调试的时候发现tocmat的东西启动还是相当多的

且看下面这个

idea tomcat启动后的数据

03-Jun-2022 10:31:30.939 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djava.util.logging.config.file=C:\Users\Administrator\.IntelliJIdea2022.3\system\tomcat\Unnamed_spring-shiro-training\conf\logging.properties

03-Jun-2022 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager

03-Jun-2022 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:52290,suspend=y,server=n

03-Jun-2022 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-javaagent:C:\Users\Administrator\.IntelliJIdea2022.3\system\captureAgent\debugger-agent.jar

03-Jun-2022 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dfile.encoding=UTF-8

03-Jun-2022 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcom.sun.management.jmxremote=

03-Jun-2022 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcom.sun.management.jmxremote.port=1099

03-Jun-2022 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcom.sun.management.jmxremote.ssl=false

03-Jun-2022 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcom.sun.management.jmxremote.password.file=C:\Users\Administrator\.IntelliJIdea2022.3\system\tomcat\Unnamed_spring-shiro-training\jmxremote.password

03-Jun-2022 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcom.sun.management.jmxremote.access.file=C:\Users\Administrator\.IntelliJIdea2022.3\system\tomcat\Unnamed_spring-shiro-training\jmxremote.access

03-Jun-2022 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djava.rmi.server.hostname=127.0.0.1

03-Jun-2022 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djdk.tls.ephemeralDHKeySize=2048

03-Jun-2022 10:31:30.940 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djava.protocol.handler.pkgs=org.apache.catalina.webresources

03-Jun-2022 10:31:30.941 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dignore.endorsed.dirs=

03-Jun-2022 10:31:30.941 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcatalina.base=C:\Users\Administrator\.IntelliJIdea2022.3\system\tomcat\Unnamed_spring-shiro-training

03-Jun-2022 10:31:30.941 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcatalina.home=D:\tomcat8.5.55\apache-tomcat-8.5.55

03-Jun-2022 10:31:30.941 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djava.io.tmpdir=D:\tomcat8.5.55\apache-tomcat-8.5.55\temp

以上还只是基本的环境配置等启动

然后是准备链接到tomcat服务

03-Jun-2022 10:31:30.941 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent 使用APR版本[1.7.0]加载了基于APR的Apache Tomcat本机库[1.2.24]。

03-Jun-2022 10:31:30.941 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR功能:IPv6[true]、sendfile[true]、accept filters[false]、random[true]。

03-Jun-2022 10:31:30.941 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL配置:useAprConnector[false],useOpenSSL[true]

03-Jun-2022 10:31:30.944 信息 [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL成功初始化 [OpenSSL 1.1.1g  21 Apr 2022]

03-Jun-2022 10:31:31.032 信息 [main] org.apache.coyote.AbstractProtocol.init 初始化协议处理器 [“http-nio-8080”]

03-Jun-2022 10:31:31.046 信息 [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read

03-Jun-2022 10:31:31.055 信息 [main] org.apache.catalina.startup.Catalina.load Initialization processed in 175489 ms

03-Jun-2022 10:31:31.080 信息 [main] org.apache.catalina.core.StandardService.startInternal 正在启动服务[Catalina]

03-Jun-2022 10:31:31.080 信息 [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.55

03-Jun-2022 10:31:31.089 信息 [main] org.apache.coyote.AbstractProtocol.start 开始协议处理句柄[“http-nio-8080”]

03-Jun-2022 10:31:31.102 信息 [main] org.apache.catalina.startup.Catalina.start Server startup in 47 ms

tomat启动主要是在Catalina中

然后是

启动

/**

* Await and shutdown.

*/

public void await() {

getServer().await();

}其实tomcat启动本质上就是socket的服务器罢了

@Override

public void await() {

// Negative values – don’t wait on port – tomcat is embedded or we just don’t like ports

if (port == -2) {

// undocumented yet – for embedding APPs that are around, alive.

return;

}

if (port==-1) {

try {

  awaitThread = Thread.currentThread();

  while(!stopAwait) {

  try {

   Thread.sleep( 10000 );

  } catch( InterruptedException ex ) {

   // continue and check the flag

  }

  }

} finally {

  awaitThread = null;

}

return;

}

// Set up a server socket to wait on

try {

awaitSocket = new ServerSocket(port, 1,

  InetAddress.getByName(address));

} catch (IOException e) {

log.error(“StandardServer.await: create[” + address

    + “:” + port

    + “]: “, e);

return;

}

try {

awaitThread = Thread.currentThread();

// Loop waiting for a connection and a valid command

while (!stopAwait) {

  ServerSocket serverSocket = awaitSocket;

  if (serverSocket == null) {

  break;

  }

  // Wait for the next connection

  Socket socket = null;

  StringBuilder command = new StringBuilder();

  try {

  InputStream stream;

  long acceptStartTime = System.currentTimeMillis();

  try {

   socket = serverSocket.accept(); //一旦accecpt后面就开始执行了

   socket.setSoTimeout(10 * 1000); // Ten seconds

   stream = socket.getInputStream();

  } catch (SocketTimeoutException ste) {

   // This should never happen but bug 56684 suggests that

   // it does.

   log.warn(sm.getString(“standardServer.accept.timeout”,

    Long.valueOf(System.currentTimeMillis() – acceptStartTime)), ste);

   continue;

  } catch (AccessControlException ace) {

   log.warn(sm.getString(“standardServer.accept.security”), ace);

   continue;

  } catch (IOException e) {

   if (stopAwait) {

   // Wait was aborted with socket.close()

   break;

   }

   log.error(sm.getString(“standardServer.accept.error”), e);

   break;

  }

  // Read a set of characters from the socket

  int expected = 1024; // Cut off to avoid DoS attack

  while (expected < shutdown.length()) {

   if (random == null)

   random = new Random();

   expected += (random.nextInt() % 1024);

  }

  while (expected > 0) {

   int ch = -1;

   try {

   ch = stream.read();

   } catch (IOException e) {

   log.warn(sm.getString(“standardServer.accept.readError”), e);

   ch = -1;

   }

   // Control character or EOF (-1) terminates loop

   if (ch < 32 || ch == 127) {

   break;

   }

   command.append((char) ch);

   expected–;

  }

  } finally {

  // Close the socket now that we are done with it

  try {

   if (socket != null) {

   socket.close();

   }

  } catch (IOException e) {

   // Ignore

  }

  }

  // Match against our command string

  boolean match = command.toString().equals(shutdown);

  if (match) {

  log.info(sm.getString(“standardServer.shutdownViaPort”));

  break;

  } else

  log.warn(sm.getString(“standardServer.invalidShutdownCommand”, command.toString()));

}

} finally {

ServerSocket serverSocket = awaitSocket;

awaitThread = null;

awaitSocket = null;

// Close the server socket and return

if (serverSocket != null) {

  try {

  serverSocket.close();

  } catch (IOException e) {

  // Ignore

  }

}

}

}

tomcat容器启动之后,下面就是Springmvc模块的内容了

到此这篇关于Idea中tomcat启动源码调试进入到tomcat内部进行调试的方法的文章就介绍到这了,更多相关Idea中tocmat启动源码调试内容请搜索共生网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持共生网络!

原创文章,作者:starterknow,如若转载,请注明出处:https://www.starterknow.com/107675.html

联系我们