允许远程调试JVM的Java命令行选项是什么?

393
我知道有一些JAVA_OPTS可用于远程调试Java程序。
它们是什么,意思是什么?
9个回答

517
在Java 5.0之前,使用-Xdebug-Xrunjdwp参数。这些选项在后续版本中仍然有效,但将以解释模式而不是JIT模式运行,速度会较慢。
从Java 5.0开始,最好使用-agentlib:jdwp单个选项:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1044

选项-Xrunjdwpagentlib:jdwp的参数如下:
  • transport=dt_socket:表示连接到JVM的方式(socket是一个不错的选择,可以用于调试远程计算机)
  • address=8000:暴露的TCP/IP端口,用于从调试器连接(仅允许本地连接,请参考Antony Shumskikh的答案以进行远程调试)
  • suspend=y:如果为'y',告诉JVM等待调试器连接后再开始执行,否则(如果为'n'),立即开始执行。

7
你说得完全正确。我尝试使用 -Xdebug-Xrunjdwp,但是没有成功。当我使用 -Xrunjdwp 或者 agentlib:jdwp 时,它可以工作。(在Java 7上) - RoboAlex
只有在我加上引号时,这才对我起作用,否则我会得到以下错误:ERROR: JDWP Non-server transport dt_socket server=y suspend=y address=8000 must have a connection address specified through the 'address=' option。 - Ring
2
Xrunjdwp 已经被弃用(或移除了)?为什么我们会选择 agentlib:jdwp 而不是它? - ArtOfWarfare
2
我认为你错了。Netbeans在调试Maven项目时使用“-Xdebug -Xrunjdwp”,它们运行起来就像是JIT编译的。 - Aleksandr Dubinsky

377

我已经将关于如何在Java 5及以下版本上进行设置的这篇文章加入了书签。

基本上,使用以下命令运行

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

对于Java 5及以上版本, 使用以下命令运行:

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

如果您希望Java在执行应用程序之前等待您连接,请将suspend=n替换为suspend=y

43
值得一提的是,您可能希望像这样配置您的地址 *:1044,以便从任何计算机启用远程调试。 - Herr Derb
9
HerrDerb 是正确的。自从 Java 9 开始,“address=1044” 并不总是在所有接口上监听。使用“address=*:1044” 可以让 Java 9+ 的行为与 Java 8 相同。 - alfonx
4
注意:不必添加address参数,如果未提供,则代理程序将选择一个随机端口号。如果您在同一Java命令行中启动多个节点,则此功能可能很有用。 - asbachb
4
使用address=localhost:<debug port>比仅选择端口更安全。 - Decoded

118

3
请注意:Oracle链接表示这将实现相同的旧行为,但不安全且不建议使用。 - Chanseok Oh
是的,我浪费了几天时间在寻找docker-compose、docker swarm debug remote with inteliji的答案上,只需按照以下方式操作(使用*:):address=*:5005 - nobjta_9x_tq
新的非死链:https://www.oracle.com/java/technologies/javase/9-all-relnotes.html - Starwarswii
一般来说,我认为绑定端口到本地主机并设置一个SSH隧道会更好(更安全,也是一种更好的实践方法)。 - Rory Browne

14

适用于Java 1.5或更高版本:

java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 <YourAppName>

对于Java 1.4版本:

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 <YourAppName>

对于Java 1.3版本:

java -Xnoagent -Djava.compiler=NONE -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 <YourAppName>

这是一个简单程序的输出结果:

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044 HelloWhirled
Listening for transport dt_socket at address: 1044
Hello whirled

10

java

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8001,suspend=y -jar target/cxf-boot-simple-0.0.1-SNAPSHOT.jar

address指定了允许调试的端口。

Maven

**使用Maven调试Spring Boot应用:

mvn spring-boot:run -Drun.jvmArguments=**"-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8001"

4

命令行

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

Gradle

gradle bootrun --debug-jvm

Maven

mvn spring-boot:run -Drun.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=PORT_NUMBER

3
这里是最简单的解决方案。
如果你使用Maven,需要许多特殊配置。所以,如果你从maven启动程序,只需运行 mvnDebug 命令而不是 mvn ,它会启动具有远程调试配置的应用程序。现在你可以在8000端口附加调试器了。
它将帮助你处理所有环境问题。

1
-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=PORT_NUMBER

在这里,我们只使用一个Socket Attaching连接器,当dt_socket传输被配置并且VM在服务器调试模式下运行时,默认情况下启用该连接器。
更多详情请参考:https://stackify.com/java-remote-debugging/

-1
如果您使用的是Java 9或更高版本,则要进行远程调试(在本地使用Docker时也是如此),您必须提供--debug *:($port)。因为从Java 9开始,--debug ($port)仅允许在本地调试,而不允许远程调试。
因此,您可以在docker-compose中提供命令,例如 command: -- /opt/jboss/wildfly/bin/standalone.sh --debug *:8787

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