前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Java远程调试(Remote Debugging)的那些事

Java远程调试(Remote Debugging)的那些事

原创
作者头像
曲水流觞
修改于 2019-11-05 08:54:44
修改于 2019-11-05 08:54:44
8.6K00
代码可运行
举报
文章被收录于专栏:曲水流觞TechRill曲水流觞TechRill
运行总次数:0
代码可运行

本文主要基于一篇英文原作翻译而成,删减部分无用文字,添加了必要的注解和补充。

*英文原文是一篇对远程调试讲解很通俗的博文: * http://blog.trifork.com/2014/07/14/how-to-remotely-debug-application-running-on-tomcat-from-within-intellij-idea/

前言

这篇文章将研究如何处理和调试那些只发生在生产环境(或其他远程环境)而本地开发环境可能没办法重现的“问题”。任何碰到过这种情况的人都不得不承认,试图定位这种“问题”原因的过程,很大可能性是以一堆胡乱猜测而告终:一个非常耗时且低效的过程。

还有一种场景, 你得到了一个可以部署的war/jar包,只有class没有java源代码,而应用部署在本地/远程后,是否可以调试? 读完本文就明白怎么做了。

配置

远程调试包括两个步骤:

  1. 启动Tomcat启用远程调试
  2. IDE (这里用IntelliJ IDEA)要能够调试远程Tomcat应用
Tomcat启用远程调试

这里有多种方法可以做到,根据tomcat所运行的操作系统而有些微的不同。但是不管用哪种方法,这些配置的背后都做了同一件事:传递特定的启动参数给 JVM,让它启用远程调试(remote debugging)。 JVM 激活远程调试的启动参数有 JPDA_OPTS, CATALINA_OPTS 和 JAVA_OPTS。其中 JAVA_OPTS 是通常不建议使用的, 因为基于 JAVA_OPTS 的参数设定会暴露给所有的 JVM 应用, 而 CATALINA_OPTS 定义的设定值限制在Tomcat 内。

1 使用JPDA_OPTS

在 CATALINA_HOME/bin 目录下创建可执行脚本文件 setenv.sh ( Windows 创建 setenv.bat ),加入内容:

Linux setenv.sh

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export JPDA_OPTS="-agentlib:jdwp=transport=dt_socket,address=1043,server=y,suspend=n"

Windows setenv.bat

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
set JPDA_OPTS="-agentlib:jdwp=transport=dt_socket,address=1043,server=y,suspend=n"

这些参数要做的事情就是启用远程调试和配置有效的选项:

  • 指定运行的被调试应用和调试者之间的通信协议,(ie: transport=dt_socket)
  • 远程被调试应用开通的端口,(ie: address=1043), 可定义其他端口,比如9999
  • server=y 表示这个 JVM 即将被调试
  • suspend=n 用来告知 JVM 立即执行,不要等待未来将要附着上/连上(attached)的调试者。如果设成 y, 则应用将暂停不运行,直到有调试者连接上

suspend=y的一个比较适用的场景是,当debug一个会阻止应用成功启动的问题时, 通过suspend=y可以确保调试者连上来之后再启动应用,否则应用已经启动报错了再调试也没意义了。*

当然上面的设置也可以直接放到 catalina.sh (catalina.bat )内,但是有个 setevn.* 额外的配置文件一直是最佳选择, tomcat会自动读取。

要注意的是, 有些人会碰到过用另一个配置方法来启用远程调试:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=1043,suspend=n

-Xdebug and -Xrunjdw 与我们上面推荐的设置不同之处在于, 它是一种旧方式,适用于JVM 小于 JAVA 5.0 的版本(包括5.0), 而 agentlib:jdwp适用于 JAVA 5.0 和以后版本。

最后通过下面的命令行启动tomcat,即可完成tomcat启用远程调试啦。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$CATALINA_HOME/bin/catalina.sh jpda start
2 使用 JAVA_OPTS / CATALINA_OPTS

如果你是在 Windows 系统把 Tomcat 作为系统服务来运行的,直接打开 Apache Tomcat 的属性对话框,在Java Tab也添加启动参数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-agentlib:jdwp=transport=dt_socket,
address=1043,server=y,suspend=n

请确保每一条配置都是新的行,参数选项之间没有空格

但如果Tomcat没有作为 Windows 系统服务, 启用方法与前面类似,在 setenv.bat 文件中写入:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
set CATALINA_OPTS="-agentlib:jdwp=transport=dt_socket,address=1043,server=y,suspend=n"

如果运行在Linux上, setenv.sh 中写入:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export CATALINA_OPTS="-agentlib:jdwp=transport=dt_socket,address=1043,server=y,suspend=n"

按照普通的方式启动Tomcat即可;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
./startup.sh
或者
./catalina.sh start
3 使用JPDA启动

最后一种启用远程调试的方式是用 JPDA 切换, 用如下的启动命令将使用默认值自动启用远程调试,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
catalina jpda start

该命令默认使用的设置是

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n

如果你想要修改默认设置中的选项怎么办?可以通过修改 Tomcat 需要的这些环境变量来实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//JPDA_TRANSPORT: 指定 jpda 传输协议
//JPDA_ADDRESS: 指定远程调试端口
//JPDA_SUSPEND: 指定 jvm 启动暂缓

export JDPA_ADDRESS=8080

然后再运行 catalina jpda start , 那么远程调试的端口将变成8080

配置Intellj Idea

确定远程 Tomcat 启动的应用已经开启了远程调试, 下一件事情就是配置Intellij Idea了。这里仍然有两种方式:Remote Tomcat 或者 Remote。

1 使用 Remote Tomcat 配置

首先保证 IDEA 里面已经打开了需要远程调试的工程源码, 然后点击 Run ➝ Edit Configurations ➝ **+ **按钮 ➝ Tomcat Server ➝ Remote

输入必要的远程 IP 地址和端口(Tomcat http端口);

然后转到 Startup / Connnection Tab 页,选择 ”Debug", 输入远程调试端口,我们例子是 1043。

保存后,开始 debug 启动远程调试,如果运行成功会显示如下的界面,然后在源码加断点开始调试。

2 使用 Remote 配置(推荐)

第一个方法有个缺陷,你打开的工程源码必须是编译通过的工程,否则会启动会报错; 而介绍的这第二种方法可以在你的工程目录乱七八糟,不是一个完整的可以部署的工程,甚至是一个解压缩的 war/ jar 的情况下都可以调试。

同上步骤,只是选择“Remote",然后输入Name, 修改Host, Port (1043) 即可, 保存后开始Debug。

设置比 Remote Tomcat 更简单,这里介绍一个实际案例。

我手里有一个可部署的war包,没有源码,在远程已经部署完毕。这时我想调试那个远程应用,怎么做呢?

解压缩war包到一个文件夹,然后用Intellij Idea打开这个文件夹,如图的结构,编译的Class都在 WEB-INF/classes 目录下

找到我要debug的那个class, 这里示例Handler.class, 通过Idea反编译出来的类代码,拷贝到一个新的文件Handler.java

虽然如图可以看到各种的编译错误,但是完全不影响你启动,代码中加断点和调试哦。

远程JVM调试怎么工作的

一切源于被称作 Agents 的东西。

运行着各种编译过的 .class 文件的JVM, 有一种特性,可以允许外部的库(Java或C++写的libraries)在运行时注入到 JVM 中。这些外部的库就称作 Agents, 他们有能力修改运行中 .class 文件的内容。

这些 Agents 拥有的这些 JVM 的功能权限, 是在 JVM 内运行的 Java Code 所无法获取的, 他们能用来做一些有趣的事情,比如修改运行中的源码, 性能分析等。 像 JRebel 工具就是用了这些功能达到魔术般的效果。

传递一个 Agent Lib 给 JVM, 通过添加 agentlib:libname[=options] 格式的启动参数即可办到。像上面的远程调试我们用的就是 **-agentlib:jdwp=... **来引入 jdwp 这个 Agent 的。

jdwp 是一个 JVM 特定的 JDWP(Java Debug Wire Protocol) 可选实现,用来定义调试者与运行JVM之间的通讯,它的是通过 JVM 本地库的 jdwp.so 或者 jdwp.dll 支持实现的。

它到底是怎么工作的呢?

简单来说, jdwp agent 会建立运行应用的 JVM 和调试者(本地或者远程)之间的桥梁。既然他是一个Agent Library, 它就有能力拦截运行的代码。

在 JVM 架构里, debugging 功能在 JVM 本身的内部是找不到的,它是一种抽象到外部工具的方式(也称作调试者 debugger)。这些调试工具或者运行在 JVM 的本地 或者在远程。这是一种解耦,模块化的架构。

更多关于远程部署相关,以及 JDWP 的深入说明,大家有兴趣可以自己研究一下。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
远程Debug Java进程的方法
远程debug的意思是启动一个Java进程,启动一个debugger进程,将两者连接起来,利用debugger来debug Java进程。
颇忒脱
2018/10/19
2.3K0
远程Debug Java进程的方法
Tomcat远程调试
命令行添加下面参数: -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n
birdskyws
2018/12/24
1.2K0
熟练使用IDEA的断点调试(Breakpoint),大大提升你调试代码的效率(行断点、属性断点、异常断点、条件断点、远程debug...)【享学Java】
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
YourBatman
2019/09/03
13.2K1
熟练使用IDEA的断点调试(Breakpoint),大大提升你调试代码的效率(行断点、属性断点、异常断点、条件断点、远程debug...)【享学Java】
Java的远程调试Remote Debug
一般开发项目时可以直接本地借助IDE工具进行debug调试,但对于线上的项目,则需要借助Java提供的远程debug功能来进行调试。可以在启动项目前通过配置对应的JVM参数来启用远程debug,也可以把参数添加到Tomcat或者Jetty之类的启动脚本里。
雨临Lewis
2022/01/12
2.4K0
IDEA实现java远程调试
启动命令中 5005就是服务对外提供的远程调试访问端口,服务器防火墙要对应开放,否则也连接不上。
终有链响
2024/07/29
1830
IDEA实现java远程调试
idea如何远程debug_eclipse远程debug原理
它的实现原理为:本机和远程主机的两个 VM 之间使用 Debug 协议通过 Socket 通信,传递调试指令和调试信息。
全栈程序员站长
2022/09/30
6040
idea如何远程debug_eclipse远程debug原理
Java安全之jar包调试技巧
suspend=n表示的是启动Java应用时是否立即进入调试模式,suspend=y表示启动即暂停,suspend=n则表示启动时不需要暂停。address=*:5005表示的是Debug监听的服务地址和端口,根据需求修改,上述配置会监听到0.0.0.0。
全栈程序员站长
2021/12/13
1.4K0
Java安全之jar包调试技巧
CVE-2024-21683:Confluence远程代码执行漏洞
Atlassian Confluence是一款由Atlassian开发的企业团队协作和知识管理软件,提供了一个集中化的平台,用于创建、组织和共享团队的文档、知识库、项目计划和协作内容,从而有效地管理项目知识和信息。Confluence 还集成了多种宏和插件,如日程表、任务列表和Jira集成。
Timeline Sec
2024/07/15
9130
CVE-2024-21683:Confluence远程代码执行漏洞
最好的IDEA debug长文?看完我佛了
最近写了几篇IntelliJ IDEA系列的文章,反响蛮好。我想了下,因为并非是分享什么破解方法、推荐插件、主题这种蛋炒饭式哗众取宠的文章,而是真实对工作有帮助,对提高工作效率很有用的内容。同学们对使用IDEA还是有不少痛点,或者姿势不够正确优雅,一直以来A哥坚持写些不随波逐流、有一定深度专栏文章,哪怕只是个工具IDEA而已。
YourBatman
2021/02/07
2.4K1
利用本地idea和tomcat 远程调试服务器部署的war包程序
这里说明一下下文“address=8000”是我在服务器开的8000端口进行调试,如果使用的是阿里云服务器需要在安全组里面添加自己想开的对应端口,必须保证我们使用的端口已经开放
鲲志说
2025/04/07
2160
利用本地idea和tomcat 远程调试服务器部署的war包程序
idea远程调试
实际开发中由于项目是部署在Linux服务器上,本地开发可以通过debug进行调试,然而在服务器上运行时出现问题无法直接定位到具体是哪行代码出现了bug,加大问题的排查,好在在idea中可以实现远程调试,本文就这个问题进行学习
在水一方
2022/06/14
9830
idea远程调试
IDEA远程调试服务端代码
需求:当我们部署在服务器中的代码线上出现问题的时候,除了tail -f xxxx查看日志外,还可以通过在 本地IDEA打断点调试远程部署在服务器的代码
关忆北.
2021/12/07
2860
IDEA远程调试服务端代码
线上Bug无法复现怎么办?老司机教你一招,SpringBoot远程调试不用愁!
前言 在部署线上项目时,相信大家都会遇到一个问题,线上的 Bug 但是在本地不会复现,多么无奈。 此时最常用的就是取到前端传递的数据用接口测试工具测试,比如 POSTMAN,复杂不,难受不? 今天陈
程序员的时光001
2020/07/14
1.3K0
线上Bug无法复现怎么办?老司机教你一招,SpringBoot远程调试不用愁!
idea如何进行debug调试_idea debug怎么用
远程调试,特别是当你在本地开发的时候,你需要调试服务器上的程序时,远程调试就显得非常有用。
全栈程序员站长
2022/10/01
1.6K0
idea如何进行debug调试_idea debug怎么用
IDEA怎么远程调试应用?
一直在纠结有没有必要写这一章的内容,毕竟网上有挺多现成的,但是为了系列文章的完整性,还是写一写。本文将结合着远程调试weblogic来讲解如何使用IDEA调试远程应用,如果你还不清楚,建议收藏,方便查阅。
tnt阿信
2020/08/05
1.9K0
IDEA怎么远程调试应用?
java实用小技巧(一)--远程debug
该系列介绍一些java开发中常用的一些小技巧,多小呢,从不会到会只需要一篇文章这么小。这一篇介绍如何使用jdk自带的扩展包配合Intellij IDEA实现远程debug。 项目中经常会有出现这样的问题,会令程序员抓狂:线上项目关键代码段没有打印日志,本地环境正常生产环境却又问题...这时候,远程debug可能会启动作用。 1 准备用于debug的代码 准备一个RestController用于接收请求,最后可以通过本地断点验证是否成功开启了远程debug @RestController public cl
kirito-moe
2018/04/27
1.8K0
java实用小技巧(一)--远程debug
详述 IntelliJ IDEA 远程调试 Tomcat 的方法
CG国斌
2018/01/08
2.4K0
详述 IntelliJ IDEA 远程调试 Tomcat 的方法
Debug 实现原理!看完还不懂吗?
我们在说起Debug的时候,一般是在IDE里代码中加断点,一步步跟踪。然后观察变量的值,观察输出等等。
终码一生
2022/04/15
6990
DWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510)异常启动tomcat的web程序时会先弹出javaw.exe「建议收藏
大家好,又见面了,我是你们的朋友全栈君。JDWP   JDWP 协议介绍   协议分析   Packet 的结构   JDWP 传输接口(Java Debug Wire Protocol Transport Interface)   JDWP 的命令实现机制   JDWP 的事件处理机制   JPDA(Java Platform Debugger Architecture) 是 Java 平台调试体系结构的缩写,通过 JPDA 提供的 API,开发人员可以方便灵活的搭建 Java 调试应用程序。JPDA 主要由三个部分组成:Java 虚拟机工具接口(JVMTI),Java 调试线协议(JDWP),以及 Java 调试接口(JDI)
全栈程序员站长
2022/08/05
5060
DWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510)异常启动tomcat的web程序时会先弹出javaw.exe「建议收藏
【IDEA】远程调试
现在很多项目都是直接部署到服务器上,通常都是没有GUI界面的,也就是说没有办法进行本地调试。在日常工作中远程调试是非常重要的一个技能,虽然说这个没办法解决线上问题,但是可以在测试环境下进行远程调试从而找到线上问题的解决方法,因为这种方式比日志更加清晰,操作难度更低。下面通过调试weblogic服务器的方式来进行举例(为什么用weblogic,因为我刚好不会哈哈,工作需要才接触的)。
秋水长天
2024/01/15
7250
推荐阅读
相关推荐
远程Debug Java进程的方法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验