远程调试Java应用程序

300

我有一个运行在Linux机器上的Java应用程序。我使用以下命令来运行Java应用程序:

java myapp -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=4000, suspend=n

我已经在这台Linux机器上打开了TCP端口4000。我从Windows XP机器使用Eclipse并尝试连接到此应用程序。我也在Windows上打开了该端口。

两台机器都在局域网中,但似乎无法将调试器连接到Java应用程序。我做错了什么?


https://dev59.com/aHI-5IYBdhLWcg3wq6do#46171836 - Alessandro Giusa
8个回答

531

编辑:我注意到有些人在这里剪贴调用。我最初给出的答案只适用于提问者。这是一个更现代的调用方式(包括使用更常规的端口8000):

java -agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=n
<other arguments>

注意:使用address=8000(如上所示),调试服务器只会监听localhost(参见如何设置Java命令行选项以允许远程调试JVM?)。如果您希望服务器监听所有接口,以便能够通过网络进行调试,请使用address=*:8000。显然,只在受限制的、可信任的网络上执行此操作...

以下是原始答案。


试试这个:

java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=4000,suspend=n myapp

这里有两点要注意:
  1. runjdwp选项中不能有空格。
  2. 选项要放在类名之前。类名后面的任何参数都是你程序的参数!

11
官方 JDPA 连接和调用文档:本文档介绍了如何使用 Java 调试协议代理 (JDPA) 建立连接并调用远程 JVM。其中包括步骤、代码示例以及相关 API 的详细说明。涵盖的主题包括:建立连接、启动调试器、传输数据等。 - Mat Gessel
3
不错!为了方便你复制粘贴,我已经更新了帖子,使用了更新的“-agentlib”选项。 :-) - C. K. Young
我们在进行远程调试时,是否总是需要在本地机器上拥有远程应用程序的源代码? - MasterJoe
你需要了解源代码。你可以拥有.java文件或者将.jar/.class文件与反编译器结合使用。像Eclipse这样的IDE可以安装反编译器,以便你可以像调试.java文件一样调试.class文件(不包括注释)。 - Iwan Satria
4
值得重复一下来自 https://dev59.com/B3VC5IYBdhLWcg3w9GA9#138518 的评论:"自从Java 9以后,“address=1044”不总是在所有接口上监听。“address=*:1044”使Java 9+的行为类似于Java 8",以允许从不同的主机进行调试。 - Marvin
显示剩余6条评论

95

对于JDK 1.3或更早版本:

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

JDK 1.4 版本

-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=6006

对于较新的 JDK:

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=6006

请根据您的需求更改端口号。

来自Java技术笔记

从5.0版本开始,选项-agentlib:jdwp用于加载和指定JDWP代理的选项。对于5.0之前的版本,使用选项-Xdebug和-Xrunjdwp(5.0实现还支持选项-Xdebug和-Xrunjdwp,但较新的选项-agentlib:jdwp更可取,因为5.0中的JDWP代理使用JVM TI接口而不是旧的JVMDI接口)

还有一件事需要注意,来自JVM工具接口文档:

JVM TI在JDK 5.0中引入。JVM TI取代了Java虚拟机分析器接口(JVMPI)和Java虚拟机调试接口(JVMDI),在JDK 6中不再提供。


以下内容适用于Eclipse的默认设置:-agentlib:jdwp=transport=dt_socket,server=y,address=8000 - Sundae

48

该页面不存在。 - Vijayan Kani
@VijayanKani 谢谢,我搜索并找到了一个更新的页面。 - M A

33

步骤:

  1. 按照上述帖子中所说的方法,使用调试选项启动您的远程Java应用程序。
  2. 通过指定主机和端口来配置Eclipse以进行远程调试。
  3. 在Eclipse中启动远程调试并等待连接成功。
  4. 设置断点并进行调试。
  5. 如果要从应用程序启动处开始调试,请使用suspend=y,这将使远程应用程序暂停,直到您从Eclipse连接它。

有关详细信息,请参见Java远程调试的逐步指南


链接中的“步骤指南”使用了一些过时的选项。 - Joshua Goldberg

16

我想强调的是参数顺序很重要

java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000 -jar app.jar命令打开了调试器端口

但是java -jar app.jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000命令没有。它会将app.jar后面的所有内容都作为命令行参数传递。


5
我猜这是因为在你的第二个例子中,“app.jar”后面的所有内容都被作为参数传递到了你的主方法中。 - xoX Zeus Xox
@xoXZeusXox 哈哈。是的,它作为参数传递了。谢谢你提醒。 - MrBlack
似乎这是Java 11中的新功能。 - petronius

3

以下是设置Eclipse远程调试器的方法:

Eclipse配置:

1.点击运行按钮
2.选择调试配置
3.选择“远程Java应用程序”
4.新建配置

  • 名称: GatewayPortalProject
  • 项目: GatewayPortal-portlet
  • 连接类型: 套接字附加(Socket Attach)
  • 连接属性: i) 主机名: localhost ii) 端口号: 8787

针对JBoss:

1.在您的VM中更改/path/toJboss/jboss-eap-6.1/bin/standalone.conf如下: 通过删除#来取消以下行的注释:

JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=n"

对于Tomcat:

catalina.bat文件中:

步骤1:

CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n"

步骤二:
JPDA_OPTS="-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n"

第三步:按照以下方式从命令提示符中运行Tomcat:
catalina.sh jpda start

然后,您需要在想要调试的Java类中设置断点。

在Java 8中,JDK支持JAVATOOL_OPTIONS环境变量,因此要为任何Java应用程序启用调试器,您需要使用:JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=np.s.对于编辑很抱歉,正在与格式化程序作斗争。 - Nathan Niesen
有关于 NetBeans 的任何想法吗? - Martynas Jusevičius

2

对于所有遇到远程调试问题的人,如果您在一台机器上进行远程调试到另一台机器,则使用:

-agentlib:jdwp = transport = dt_socket,server = y,address = 8000,suspend = n

是不够的,因为它现在绑定到本地主机(至少在unix / osx机器上),所以您只能从本地主机连接到它。

如果您尝试远程调试,则会收到连接被拒绝的错误。我认为从Java 9开始,您需要执行以下操作:

-agentlib:jdwp = transport = dt_socket,server = y,address = *:8000,suspend = n

或者给出一个IP地址,它需要绑定到hat *。


0
每个解决方案都在描述应用程序启动后附加调试器的方法。 在“调试器监听”设置中,您需要设置server=n和suspend=n。如果不这样做,Gradle将抛出权限被拒绝的错误。

build.gradle:

run {
    jvmArgs = ["-agentlib:jdwp=transport=dt_socket,server=n,suspend=n,address=5005"
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接