Debugging of a JVM application (Java or Scala) wit

2019-05-18 12:12发布

问题:

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:

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

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

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?

回答1:

Debugging of gradle tasks like 'test', 'run', actually all gradle tasks that implements JavaForkOptions interface, should work in IntelliJ since 2014 year



回答2:

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:

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

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

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.