Tomcat debug模式启动

2023-11-01

在%CATALINA_HOME%\bin\startup.bat中添加以下任意一行配置: 
SET JAVA_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n 

SET CATALINA_OPTS=-server -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8787 


启动tomcat后,在控制台显示以下内容表示配置成功: 

Listening for transport dt_socket at address: 8787


JPDA简介

顾名思义,JPDA为Java平台上的调试器定义了一个标准的体系结构。该体系结构包括3个主要组成部分:JVM TI、JDI和JDWP。

 

JVM TI的全称是Java Virtual Machine Tool Interface,它定义了JVM为了支持调试而必须提供的功能及相应的访问接口。这些访问接口是以本地语言的形式提供的,由JVM(比如Sun公司的HotSpot VM)负责实现。

不过,JVM TI只是JVM提供的一系列函数,调试器(特别是远程的调试器)如何调用呢?其实啊,JVM TI的直接客户端并不是调试器,而是一个称为“JPDA back-end”的东东。这个东东应该是属于JVM的一部分,在SUN JRE的bin目录下可以找到jdwp.dll(jdwp.so)的库文件,这就是JPDA back-end的实现。按我理解,JPDA back-end提供了各种访问方式(共享内存,Socket),通过这些方式接收调试器的请求,然后调用JVM TI接口。

 

JDI的全称是Java Debug Interface,它定义了访问JVM TI接口的高层API,以纯Java语言提供,由JDK实现(在Sun JDK的tools.jar可以找到)。调试器直接使用JDI来实现调试的功能。与JPDA back-end相对应,JDI实现的角色就是JPDA front-end。

 

JDWP的全称是Java Debug Wire Protocol,它定义了JPDA front-end和JPDA back-end之间通讯信息的二进制格式。这里的通讯信息主要包括两种:调试器发送给JVM的请求信息和JVM发送给调试器的调试信息。

 

总结一下,调试器 调用JDK提供的JDI实现 (JPDA front-end),经由JDWP协议 ,和JVM自带的JPDA back-end(jdwp.dll, jdwp.so, ...)进行通讯。JPDA back-end 通过调用JVM TI接口 ,从而获知调试信息,或发送控制命令。然后,JPDA back-end 将调试信息或命令执行结果,通过JDWP协议 ,返回给调试器 。

 

如何启用JPDA

默认情况下,JVM并没有启用JPDA back-end。需要在启动JVM的命令行加载以下参数:

-Xdebug

-Xrunjdwp:transport=dt_socket, address=8000,server=y,suspend=y

 

-Xdebug

启用调试特性

-Xrunjdwp

启用JDWP实现,它包含若干子选项:

transport=dt_socket

JPDA front-end和back-end之间的传输方法。dt_socket表示使用套接字传输。

address=8000

JVM在8000端口上监听请求。

server=y

y表示启动的JVM是被调试者。如果为n,则表示启动的JVM是调试器。

suspend=y

y表示启动的JVM会暂停等待,直到调试器连接上。

 

suspend=y这个选项很重要。如果你想从Tomcat启动的一开始就进行调试,那么就必须设置suspend=y。

 

Tomcat的启动脚本

只要Tomcat启动时,启用了JPDA,那么就可以被调试。而Tomcat默认是不启用JPDA的,需要我们手动开启。

 

开启JPDA的方法也很简单,对Tomcat的启动脚本做点修改,把启动JPDA的命令行参数添加进去,就可以了。

 

不过Tomcat启动脚本还是有点复杂的,并不是简单的”java ...“。我们先简单的梳理一下。

 

在Tomcat 5.5.26发行版的bin目录下,有N多脚本,其中与Tomcat启停有关的脚本是(以Windows为例):

startup.bat        //启动Tomcat

shutdown.bat   //停止Tomcat

catalina.bat       //包含启动/停止Tomcat的核心逻辑

 

startup.bat和shutdown.bat都是通过调用catalina.bat来实现启动和停止的功能,因此他俩的代码都很少。主要的逻辑都在catalina.bat中。

 

catalina.bat是个强大的脚本,通过参数,可以执行各种动作,包括debug run start stop version等。

如果我们直接执行catalina.bat,就可以看到它的用法说明:

 

直接执行catalina.bat时的输出

 

startup.bat,其实就是执行catalina.bat start;shutdown.bat,其实就是执行catalina.bat stop。

不难猜到,我们可以写一个jdpa.bat,直接调用catalina.bat jpda start,应该就可以启用JPDA。我们拷贝一份startup.bat,把下面这行

call "%EXECUTABLE%" start %CMD_LINE_ARGS%

修改成

call "%EXECUTABLE%" jpda start %CMD_LINE_ARGS%

 

不过,-Xdebug -Xrunjdwp:transport=dt_socket, address=8000,server=y,suspend=y,这些选项参数怎么传递给catalina.bat呢?

看看catalina.bat前面的注释,server的值默认就是y,transport的值是变量JPDA_TRANSPORT,address的值是变量JPDA_ADDRESS,suspend的值是变量JPDA_SUSPEND 。如果没有显式地复制,这些变量的值默认是dt_shmem jdbconn n(默认值表示使用共享内存作为传输方式)。这些默认值不是我们需要的,Eclisep的远程调试目前只支持套接字传输。在调用catalina.bat jpda start之前,我们给这些变量设置恰当的值:

set JPDA_TRANSPORT=dt_socket
set JPDA_ADDRESS=8000
set JPDA_SUSPEND=y

call "%EXECUTABLE%" jpda start %CMD_LINE_ARGS%

 

然后,直接执行jpda.bat,Tomcat就运行在JPDA可调式模式下:

启用JPDA的Tomcat

 

从上图可以看出,Tomcat的JPDA使用套接字传输,监听在8000端口。Tomcat的启动已经暂停,只有调试器连接上来,才会继续启动。

 

我把jpda.bat的完整内容列在下面,其中黑体部分,在startup.bat基础上添加的代码:

 


 

@echo off
if "%OS%" == "Windows_NT" setlocal
rem ---------------------------------------------------------------------------
rem Jpda script for the CATALINA Server
rem
rem $Id: jpda.bat 302918 2004-05-27 18:25:11Z yoavs $
rem ---------------------------------------------------------------------------

rem Guess CATALINA_HOME if not defined
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
:okHome

set 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
:okExec

rem 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
:doneSetArgs

set JPDA_TRANSPORT=dt_socket
set JPDA_ADDRESS=8000
set JPDA_SUSPEND=y
 

call "%EXECUTABLE%" jpda start %CMD_LINE_ARGS%

:end

 


 

 

在Eclipse中远程调试Tomcat

首先将Tomcat 5.5.26的源代码分为container connectors jasper servletapi build五个项目,导入到Eclipse中。启动相关的代码主要在container中,就以它为当前项目,打开”Debug Configurations“对话框。

然后创建一个”Remote Java Application“,Connection Type选择”Standard (Socket Attach)“,Host填写localhost(Tomcat所在的主机地址),Port填写8000。最后点击”Apply“保存。

Eclipse的Debug Configurations对话框中配置远程调试

 

首先确保已经执行了jpda.bat,Tomcat正在等待调试器连接;然后执行上述的Debug Configuration,Eclipse就可以连上Tomcat。

 

Tomcat的启动是从Bootstrap的main方法开始,我在第一行代码处设置了断点,Tomcat的启动就停在了这一行:

 

断点调试Tomcat的启动过程

 

接着,让Tomcat继续执行,我们可以看到,控制台输出了启动信息。

Tomcat在JPDA模式下继续启动


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Tomcat debug模式启动 的相关文章

  • Spring Batch 多线程 - 如何使每个线程读取唯一的记录?

    这个问题在很多论坛上都被问过很多次了 但我没有看到适合我的答案 我正在尝试在我的 Spring Batch 实现中实现多线程步骤 有一个包含 100k 条记录的临时表 想要在 10 个线程中处理它 每个线程的提交间隔为 300 因此在任何时
  • Java - 将节点添加到列表的末尾?

    这是我所拥有的 public class Node Object data Node next Node Object data Node next this data data this next next public Object g
  • 如何找到给定字符串的最长重复子串

    我是java新手 我被分配寻找字符串的最长子字符串 我在网上研究 似乎解决这个问题的好方法是实现后缀树 请告诉我如何做到这一点或者您是否有任何其他解决方案 请记住 这应该是在 Java 知识水平较低的情况下完成的 提前致谢 附 测试仪字符串
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • 反射找不到对象子类型

    我试图通过使用反射来获取包中的所有类 当我使用具体类的代码 本例中为 A 时 它可以工作并打印子类信息 B 扩展 A 因此它打印 B 信息 但是当我将它与对象类一起使用时 它不起作用 我该如何修复它 这段代码的工作原理 Reflection
  • JavaMail 只获取新邮件

    我想知道是否有一种方法可以在javamail中只获取新消息 例如 在初始加载时 获取收件箱中的所有消息并存储它们 然后 每当应用程序再次加载时 仅获取新消息 而不是再次重新加载它们 javamail 可以做到这一点吗 它是如何工作的 一些背
  • Liferay ClassNotFoundException:DLFileEntryImpl

    在我的 6 1 0 Portal 实例上 带有使用 ServiceBuilder 和 DL Api 的 6 1 0 SDK Portlet 这一行 DynamicQuery query DynamicQueryFactoryUtil for
  • 磁模拟

    假设我在 n m 像素的 2D 表面上有 p 个节点 我希望这些节点相互吸引 使得它们相距越远吸引力就越强 但是 如果两个节点之间的距离 比如 d A B 小于某个阈值 比如 k 那么它们就会开始排斥 谁能让我开始编写一些关于如何随时间更新
  • Mockito when().thenReturn 不必要地调用该方法

    我正在研究继承的代码 我编写了一个应该捕获 NullPointerException 的测试 因为它试图从 null 对象调用方法 Test expected NullPointerException class public void c
  • 如何为俚语和表情符号构建正则表达式 (regex)

    我需要构建一个正则表达式来匹配俚语 即 lol lmao imo 等 和表情符号 即 P 等 我按照以下示例进行操作http www coderanch com t 497238 java java Regular Expression D
  • Java TestNG 与跨多个测试的数据驱动测试

    我正在电子商务平台中测试一系列商店 每个商店都有一系列属性 我正在考虑对其进行自动化测试 是否有可能有一个数据提供者在整个测试套件中提供数据 而不仅仅是 TestNG 中的测试 我尝试不使用 testNG xml 文件作为机制 因为这些属性
  • 如何在 javadoc 中使用“<”和“>”而不进行格式化?

    如果我写
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • 使用 JMF 创建 RTP 流时出现问题

    我正处于一个项目的早期阶段 需要使用 RTP 广播DataStream创建自MediaLocation 我正在遵循一些示例代码 该代码目前在rptManager initalize localAddress 出现错误 无法打开本地数据端口
  • 当我从 Netbeans 创建 Derby 数据库时,它存储在哪里?

    当我从 netbeans 创建 Derby 数据库时 它存储在哪里 如何将它与项目的其余部分合并到一个文件夹中 右键单击Databases gt JavaDB in the Service查看并选择Properties This will
  • 如何实现仅当可用内存较低时才将数据交换到磁盘的写缓存

    我想将应用程序生成的数据缓存在内存中 但如果内存变得稀缺 我想将数据交换到磁盘 理想情况下 我希望虚拟机通知它需要内存并将我的数据写入磁盘并以这种方式释放一些内存 但我没有看到任何方法以通知我的方式将自己挂接到虚拟机中before an O
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j

随机推荐

  • 【深度学习】Pytorch 系列教程(十一):PyTorch数据结构:3、变量(Variable)介绍

    目录 一 前言 二 实验环境 三 PyTorch数据结构 0 分类 1 张量 Tensor 2 张量操作 Tensor Operations 3 变量 Variable 一 前言 ChatGPT PyTorch是一个开源的机器学习框架 广泛
  • java web实验2客户端综合编程

    一 实验目的与要求 简述本次实验要求达到的目的 涉及到的相关知识点 实验的具体要求 1 实验目的 1 编写HTML网页 掌握HTML表单 表格等常用标签的使用 掌握CSS的语法和应用 2 编写JavaScript代码 熟悉并掌握JavaSc
  • ctk插件框架异常:The service interface class has no Q_DECLARE_INTERFACE macro

    ctk插件框架异常 The service interface class has no Q DECLARE INTERFACE macro 前言 当调试ctkPluginFramework时 抛出异常 throw ctkServiceEx
  • 【2022第十届‘泰迪杯’挑战赛】A题:害虫识别完整版(大致思路。详细过程和代码以及结果csv在压缩包中)

    2022第十届 泰迪杯 挑战赛 A题 害虫识别完整版 已有完整结果 2022泰迪杯挑战赛A题害虫识别完整版 大致思路 详细过程和代码在压缩包中 正式数据 2022 04 06 正式数据 提取码 u54n 写在前面 完整版下载 建议Chrom
  • ios备忘录下载安卓版_ios8备忘录app软件下载

    ios8备忘录最新版是一款可以在手机上安装ios8专用备忘录的软件 可以快速记录事件 支持语音输入 还可以合并多个便签 超多样式可以自己选择 感受全新的记录体验 软件的功能众多 还可以设置定时提醒功能 快来试试吧 ios8备忘录软件介绍 你
  • Latex

    http www tablesgenerator com 表格神器 LibreDigitalLibrary github io 印度人搜集的教育资源 1 MCM The Mathematical Contest in Modeling ht
  • java创建以任意图片为背景的窗口

    swing自带的窗体是不能够满足我们的应用需求的 所以需要制作任意图片和形状的JFrame框体 比如下图 并且可以设置窗体背景图片的透明度 下面说明如何做到上图的效果 1 首先你得需要一张好看的图片 比如羊皮纸 但是这个下载的图片是方方正正
  • 处理中文乱码

    处理传输中文乱码 String shopProductName request getParameter shopProductName if org springframework util StringUtils isEmpty sho
  • 雷达手势识别技术概述

    前言 不必害怕未知 无需恐惧犯错 做一个Creator 目录 前言 雷达技术特点 毫米波雷达 实现过程 手势信号预处理 手势特征提取与分类识别算法 雷达技术特点 随着雷达技术的快速发展和广泛应用 雷达手势识别已成为人机交互技术领域的一个重要
  • LoadRunner解决动态验证码问题

    对于这个问题 通常我们可以采取以下三个途径来解决该问题 1 第一种方法 也是最容易想到的 在被测系统中暂时屏蔽验证功能 也就是说 临时修改应用 无论用户输入的是什么验证码 都认为是正确的 这种方法最容易实现 对测试结果也不会有太大的影响 当
  • Linux命令之sync

    概述 sync 命令可以强制将内存中的文件缓冲写入磁盘 更新块信息 在 linux unix 系统中 在文件或数据处理过程中一般先放到内存缓冲区中 等到适当的时候再写入磁盘 以提高系统的运行效率 这样虽然可以提高磁盘写入数据的效率 但是也带
  • STM32高级定时器中心对齐PWM模式,频率设置的分享

    有关STM32高级定时器中心对齐PWM输出的实验记录 计算PWM的频率公式 f PCLK2 TIM Prescaler 1 TIM Period 1 2 条件TIM ClockDivision 0 而不是f PCLK2 TIM Presca
  • 单链表的定义,插入与删除,查找,建立。

    链表分为 单链表 双链表 循环链表 静态链表 一 单链表的定义 在内存空间中 各个节点在逻辑上相邻 但在物理上不相邻 在单个的结点内部需要存放 数据域 和 指针域 存放指向下一个结点的指针 优点 不要求一大片连续空间 改变容量方便 缺点 不
  • InVideo AI:用人工智能轻松制作视频

    简介 InVideo AI 是一款在线视频制作工具 使用人工智能来帮助用户快速 轻松地制作高质量的视频 该工具提供多种功能 包括 链接 ai invideo io 仪表盘 历史记录 创建视频 选择模板 youtube explainer 加
  • 关于华硕飞行堡垒8笔记本网卡启动不了(Inter(R) Wi-Fi 6 AX201)该设备无法启动 代码10

    今天打开笔记本莫名奇妙的 连不上WIFI了 网线可以联网 查看设备管理器 网卡亮感叹号 查看详情 提示 该设备无法启动 代码10 代码10有三个情况 1 驱动不合 概率少 2 系统不合 小概率 3 坏了 大概率 解决方案也就是 1 重装网卡
  • proc文件系统下各参数解析

    文章目录 一 proc文件系统 1 1 proc pid 1 1 1 proc pid arch status 1 1 2 proc pid attr 1 1 2 1 proc pid attr current 1 1 2 2 proc p
  • 【华为OD机试真题2023B卷 JS】比赛的冠亚季军

    华为OD2023 B卷 机试题库全覆盖 刷题指南点这里 比赛的冠亚季军 知识点数组编程基础链表分治 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 有N 3 lt N lt 10000 个运动员 他们的id为0到N 1 他们
  • 如何使用pandas读取csv文件中的某一列数据

    使用pandas读取csv文件中的某一列数据 可以这样做 先导入pandas模块 import pandas as pd 使用pd read csv函数读取csv文件 df pd read csv 文件名 csv 使用df 列名 读取某一列
  • 矩阵的转置(c++)

    将一个m n的二维数组的行和列元素互换 如下图所示 注 T代表转置 输入格式 输入矩阵的行和列数 用空格隔开 接下来输入矩阵的数据 1
  • Tomcat debug模式启动

    在 CATALINA HOME bin startup bat中添加以下任意一行配置 SET JAVA OPTS Xdebug Xrunjdwp transport dt socket address 8787 server y suspe