Search code examples
debuggingintellij-ideagradlejvmbreakpoints

Debugging of a JVM application (Java or Scala) with breakpoints in Gradle and IntelliJ 2016.3.5


I have a JVM application that I need to debug using breakpoints with a Gradle task (run and test as dependencies) within IntelliJ 2016.3.5.

There are various sources on how to accomplish debugging with Gradle and IntelliJ:

  1. Debug Gradle plugins with IntelliJ
  2. Using Intellij to set breakpoints in gradle project (most helpful one)
  3. https://youtrack.jetbrains.com/issue/IDEA-119551
  4. https://youtrack.jetbrains.com/issue/IDEA-86465
  5. https://youtrack.jetbrains.com/issue/IDEA-119494

However, these sources are either outdated or meant for another scenario. I do not want to debug the Gradle script but the JVM that runs the actual Java/Scala application. Moreover, the recent versions of IntelliJ use the Gradle Tooling API, which does not offer the option to turn off the daemon. A native support from JetBrains is only provided using the debugging button on the run and test tasks directly, but not if they are defined as dependencies from another task (e.g., check).

According to the sources, this is the way to go then:

run { // or test, doesn't matter
    jvmArgs "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"
    // xor, or both, doesn't seem to make any difference
    debug true
}

In any way, Gradle (or the JVM) will then start to listen on port 5005:

Imgur

Then, I have created a remote configuration with the following parameters:

Imgur

But when I start the IntelliJ remote debugging task, it fails:

Imgur

I have also tried using port 5006 and suspend=n without success. Before that, I tried using Gradle arguments in the IntelliJ-Gradle run task. Then, it indeed connected, but seemingly to the Gradle script and not the application JVM because it did not interrupt at the breakpoints. How to fix this?


Solution

  • Meanwhile, I found the solution myself. If you have a similar issue, follow the approach mentioned above using the debug option.

    test {
        debug true
    }
    

    But make sure that external connections are accepted in the settings after IntelliJ restarted:

    Imgur

    Imgur

    Then, it connects to the correct JVM and interrupts at the breakpoints using the remote task:

    Imgur

    Imgur

    If you restart IntelliJ, however, with the very same option (external connections) enabled, then the debugging task might fail due to a blocked port:

    Imgur

    So, for some reason, IntelliJ blocks that port after a restart but it is necessary to enable the setting for the debugging task to work. That's odd and I don't think it is intended to behave like that.

    Anyways, if you disable the setting and restart, the port will be open again. Then, re-enable the setting, do not restart, just run the Gradle task, and the debugging task. It will work.

    I hope this helps anyone else looking for an intermediate solution to debug JVM applications with Gradle and IntelliJ among the confusing and partially outdated answers out there. If anyone has a better or simpler suggestion, feel free to append your answer.