Remote debug a JUnit test executed using Gradle

I have the following scenario:

Machine A: Executing a JUnit test using Gradle:

./gradlew :<directory> --tests <ClassName> --info

Machine B: I have an IDE (like IntelliJ). I want to create a remote Java debug configuration to machine A and debug the test.

I came across “–debug-jvm” option for gradlew for remote debug. Using this parameter, the Gradle test runner is getting suspended on port 5005 by default. I can connect to this process only from the same machine (machine A) but not from machine B.

I followed the steps mentioned at Debugging with Gradle – dead fish But even with this configuration, I am unable to debug from machine B. I always get “Connection refused” error from the IDE in machine B.

With Gradle’s --info option, I can see the following parameters added to JVM started for running the tests:

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

For remote debugging I believe address should have “*:” before the port number. For example:

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

But the “–debug-jvm” is not adding “*:” to the parameters.

Also tried the following things:

  1. Adding “debugOptions” to the Gradle’s “test” task: debugOptions { enabled = true port = 8166 server = true suspend = true } The result is the same. Not able to connect from machine B and results in “Connection refused” error in IDE.
  2. Adding following properties to gradle.proprties:

org.gradle.daemon=false

org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:10999

Gradle’s daemon thread is suspended with the above properties but not the test executor thread.

Gradle version: 5.6.2
Java version: JDK 11

Things are working if everything (running the tests and IDE) is on a single machine.

So the question is, how to really “remote” debug a JUnit test that is executed using Gradle?

Thanks for your help!

Well, it seems the test task is only designed to allow local debugging.
You should probably open a feature request that you can also configure remote debugging.

But you actually have at least two ways to mitigate the missing feature.

You can either connect via SSH from B to A and thereby open a TCP tunnel, so that for the debugee the connection looks like it is local.

Or you can use jvmArgs on the test task to give it the exact debug arguments you want like the one you have to org.gradle.jvmargs for example.

@Vampire Thanks for the reply. I tried ‘jvmArgs’ and it worked. Thanks again!

I also stumbled across the address/port issue . Since Java-11 you are advised to specify an address instead just a plain port. Java-1.8 still provided the possibility to specify the hostname:port. Since Java-11 the “*:port” notation can be used.
The gradle [Debug-DSL] (Testing in Java & JVM projects) interprets the address just as a port … which is incorrect.

How can the feature-request/adjustment be filed ?

Since Java-11 you are advised to specify an address instead just a plain port.

Where?
Never personally heard of that yet.
Where do you have that from?

Java-1.8 still provided the possibility to specify the hostname:port . Since Java-11 the “*:port” notation can be used.

It can be used, but why should it be used by default?
It opens the debugger on any network address, which is a pretty bad idea as a default setting,
as that means anyone reaching your computer could attach his debugger to your debugee.
That would be a critical default value and a very bad idea imho.

Just using a port imho is still the best default as it just opens the debugger port on localhost (which typically is 127.0.0.1, but does not have to be) and works without problem even in Java 17.

How can the feature-request/adjustment be filed ?

I agree that it should be configurable, but I fully disagree that the default value should open your debugee to the world.
As I said before, you should probably open a feature request that you can also configure remote debugging at Sign in to GitHub · GitHub

I have to correct my statement - Notes and Changes

JDWP socket connector accept only local connections by default

The JDWP socket connector has been changed to bind to localhost only if no ip address or hostname is specified on the agent command line. A hostname of asterisk (*) may be used to achieve the old behavior which is to bind the JDWP socket connector to all available interfaces; this is not secure and not recommended.

JDK-8041435 (not public)

core-svc/java.lang.instrument

I completely agree with you about the problematic *:port usage. I just wanted to mention that I was missing the possibility to specify the address parameter in debug options which is just exposed as an port number .
I see there is already an open request … "--debug-jvm" broken since JDK 9 when running Gradle inside a container and debugging from the host · Issue #7496 · gradle/gradle · GitHub
Thanks for the feedback

1 Like