I want to debug some JVM instances that are running at the same time. I know that I can run gradle using --debug-jvm
so that the JVM will wait until I start the IDE debugger so that it connects to the JVM but it uses port 5005 by default. That's fine for debugging one instance of JVM... but if I want to debug more than one instance, I'll need to define a different port from 5005. How can I achieve this with gradle?

- 26,375
- 3
- 36
- 60
-
Can’t you just use integrated tools to launch in debug mode with Gradle? I know IntelliJ just lets me start a gradle process and I can still debug the code. – vandench Nov 16 '18 at 19:23
-
Short answer: *no*. Long answer: No, because I'm using a script that is running many different things ending up with a gradle call. – eftshift0 Nov 16 '18 at 19:26
4 Answers
In my case I wanted to debug a specific file, so I included the following code in build.gradle
:
task execFile(type: JavaExec) {
main = mainClass
classpath = sourceSets.main.runtimeClasspath
if (System.getProperty('debug', 'false') == 'true') {
jvmArgs "-Xdebug", "-agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=y"
}
systemProperties System.getProperties()
}
and I can run with:
gradle execFile -PmainClass=com.MyClass -Dmyprop=somevalue -Ddebug=true
The custom execFile
task receives:
-PmainClass=com.MyClass
: the class with the main method I want to execute (in the script,main = mainClass
)-Dmyprop=somevalue
: a property whose value be retrieved in the application callingSystem.getProperty("myprop")
(in the script,systemProperties System.getProperties()
was needed for that)-Ddebug=true
: a flag to enable debugging on port 8787 (in the script, see theif
condition, and alsoaddress=8787
, but the port could be changed, and this flag name also could be changed). Usingsuspend=y
the execution is suspended until the debugger is attached to the port (if you don't want this behaviour, you could usesuspend=n
)
For your use case, you could try to apply the logic behind the line jvmArgs ...
to your specific task (or use tasks.withType(JavaExec) { ... }
to apply to all tasks of this type).
Using this solution, don't use the --debug-jvm
option because you may receive an error about the property jdwp
being defined twice.
Update (2020-08-10)
To make sure that the code runs only when I execute the task execFile
explicitly (so as to not run when I just build gradle, for example), I changed the code to:
task execFile {
dependsOn 'build'
doLast {
tasks.create('execFileJavaExec', JavaExec) {
main = mainClass
classpath = sourceSets.main.runtimeClasspath
if (System.getProperty('debug', 'false') == 'true') {
jvmArgs "-Xdebug", "-agentlib:jdwp=transport=dt_socket,address=*:8787,server=y,suspend=y"
}
systemProperties System.getProperties()
}.exec()
}
}
See more at: Run gradle task only when called specifically

- 7,260
- 2
- 47
- 61
-
With Java11 I created this kind of task with Spring Boot and Vagrant to enable remote debug: task debug(type: JavaExec) { main = mainClass classpath = sourceSets.main.runtimeClasspath jvmArgs "-agentlib:jdwp=transport=dt_socket,address=192.168.133.10:5005,server=y,suspend=y" systemProperties System.getProperties() } – PHZ.fi-Pharazon Aug 09 '20 at 19:57
-
@PHZ.fi-Pharazon If you want to make sure that the code runs only when you call `execFile` explicitly, you can use the new code I included, in which the `JavaExec` task is created in a `doLast`. – Lucas Basquerotto Aug 10 '20 at 12:05
You could modify GRADLE_OPTS
environment variable and add standard Java debugger syntax e.g. to use port 8888:
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8888

- 43,645
- 9
- 78
- 111
-
2This looked promising... but debugger fails to stop on a breakpoint I set on the project. If I use --debug-jvm and connect using port 5005, it stopped as expected. I guess there's something missing. – eftshift0 Nov 16 '18 at 19:57
-
@eftshift0 Perhaps the Gradle daemon is running in the background. Can you try with `--no-daemon`? – Karol Dowbecki Nov 16 '18 at 19:57
-
that would be one option on the gladle call or an additional option on GRADLE_OPTS? – eftshift0 Nov 16 '18 at 20:00
-
@eftshift0 yes, as per [docs](https://docs.gradle.org/current/userguide/gradle_daemon.html) – Karol Dowbecki Nov 16 '18 at 20:02
-
-
1I _think_ this is setting the JVM args for the Gradle process/daemon, and not the forked JavaExec process. See Lucas Basquerotto's answer. – badsyntax Apr 25 '20 at 09:51
Option 1 - Directly pass the JVM arguments that start up the debugger
task exampleProgram(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
description = "Your Description"
main = 'Example.java' // <package>.<path>.<to>.<YourMainClass>.java
// Change `1805` to whatever port you want.
jvmArgs=["-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=1805"]
}
If it doesn't work right away, try stopping all existing Daemons with gradle --stop
so Gradle isn't influenced by any past settings when building/running your project.
Option 2 - Use Gradle's debugOptions
object
Alternatively, according to Gradle's documentation, the following should also do the trick; however, it didn't work for me. I'm including it for completeness and in the hope that it works in the future.
task runApp(type: JavaExec) {
...
debugOptions {
enabled = true
port = 5566
server = true
suspend = false
}
}
References:
- JVM Debugger Args: https://docs.oracle.com/cd/E19146-01/821-1828/gdabx/index.html
- Similar question: how to debug spring application with gradle

- 913
- 10
- 18
Option 2 - Use Gradle's debugOptions object
For Grails5 in build.gradle i put debugOptions into bootRun section:
bootRun {
...
jvmArgs(
// whatever extras you need...
)
debugOptions {
//enabled = true
port = 5566
server = true
suspend = false
}
...
}
Then run grails with or without --debug-jvm switch at the end of arguments list to turn it on/off.
You may also uncomment "enabled=true" to always run in debug mode without passing --debug-jvm.

- 1
- 2