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

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:
Debug Gradle plugins with IntelliJ
Using Intellij to set breakpoints in gradle project (most helpful one)
https://youtrack.jetbrains.com/issue/IDEA-119551
https://youtrack.jetbrains.com/issue/IDEA-86465
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?

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

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.

Related

SpringBoot Kotlin project wont run and debug from Intellij

We have inherited a SpringBoot project written in Kotlin. Using Intellij, I would expect to be able to go to the Application main method and click the green arrow to start the project. I would also expect to be able to run the project in debug mode and set breakpoints, this only works with tests.
When I try and run the project I get a exception FileNotFound which has yielded me no answers. Every file appears to be accounted for and there is clearly nothing missing.
This is a multi-module gradle project with many unique configurations and I suspect one is causing an issue. I am having trouble determining which configuration is causing the issue because the project doesn't even seem to get to the point of standing up Spring (no banner).
I have tried many different combinations of bash scripts, environment variables, and gradle tasks and the project does not seem to run at all. Is there any way I can use Intellij to debug the sequence of configurations and gradle tasks?
So, I am answering my own question because searches lead me nowhere and this was a surprisingly difficult problem to debug. It turns out I was taking the wrong approaches and asking the wrong questions. I took a lot of time to study up on Spring configurations and Gradle tasks to realize none of our stuff was wrong. The Kotlin compiler was failing at the very beginning.
What had happened was one developer naively cd'ed into the Application's module and ran an echo statement that piped gradle output to a file called out with no extensions.
Kotlin would find this file and then proceed to not compile anything starting at the Application main. When we ran the app from terminal the app would recompile itself from the very beginning with no problems. But the automatically generated Intellij config simply ran the app with the bad file every time.
The troubling part was that our .gitignore file was configured to ignore all of the kotlin /out/ directories, but not files like /out so this troublesome file was committed to the repository for quite a while.
Surprisingly, deleting this out file fixed most of the issues our project had with Intellij.
Another note:
Our script was also set to source certain variables from other scripts, which meant we either had to carry them over to the runtime configs. We could also run Intelli from the same terminal we had already sourced the script in (using Tools> Create command line launcher). Once I had that sorted the project ran and debugged perfectly.

how to debug spring boot gradle projects faster in intellij idea?

When I develop spring boot gradle projects in intellij idea, if I want to change some code and restart the project, I have to click the Make Project menu item and this will trigger a gradle build.If the gradle deamon is dead, it will start first which is an upset process.
While in Spring Tool Suite, everything is so easy, just Ctrl S and STS will restart immediately witout the long gradle build. So is there any way to make intellij idea restart faster?
I know if the gradle deamon is alive, gradle build in intellij idea is not very slow and is acceptable. But on my computer, the deamon can usually live for only several minites. When I change some codes and want to see the effects, the deamon died. I have to start the deamon every time! Is there any other ways to make the deamon live longer?
Thanks a lot if there is any useful tips!
Well, thanks to #Gregg and #CrazyCoder 's comment, I found some useful links:
Developing/Debugging a Gradle-built Spring Boot app in IntelliJ IDEA
I accidently enable the delegate to gradle option in idea, which will trigger gradle build instead of idea's build, which is faster than gradle's. So disable the delegate to gradle option is a choice.
From another post, I get some idea to use the continuous build in gradle: open a terminal and run gradle assemble --continuous, when files are changed(for example save files or defocus window), gradle will compiles files automatically. Then run the spring boot app use gradle bootRun or from the tasks in idea, everything is ok. But this way will start two gradle so ram usages are larger.
Update:
I found another way to automatically compile. Fisrt, enable build project automatically option, then use ctrl shift a and input registry to open a dialog, and then enable compiler.automake.allow.when.app.running opiton. Finally, project will compile automatically and spring boot will also restart automatically.

Debugger doesn't stop at break points (Arquillian, TomEE, OpenJPA Enhancer, Maven, JUnit, and IntelliJ)

I'm writing a web app that uses JAX-RS (Apache CXF) and JPA (Apache OpenJPA) and is deployed using TomEE+. I've started using Arquillian via the arquillian-tomee-embedded maven dependency to unit test my REST services.
When I use IntelliJ to launch the test phase of Maven's build lifecycle everything works great. It runs OpenJPA's enhancer on my JPA Entities, kicks off the unit tests, and I'm able to successfully call my web services and they're able to successfully access the database.
Unfortunately, if I launch the test phase in debug mode everything still works but none of my breakpoints hit. What must I do to correct this problem?
I've found a tedious workaround. I can right click each unit test and run in debug mode and the debugger will hit breakpoints...but I have to manually run the OpenJPA enhancer beforehand in order for the JPA code to work.
When you "launch the test phase in debug mode ", it means that Maven runs in debug mode, not that it debugs your app. You cannot debug your app through maven. Maven runs the tests using surefire-plugin, and you cannot use breakpoints and debug.
There can be two possibilities:
1) The code / break-point(s) are not reachable / not getting called with current context.
2) You are NOT running application in Debug mode.
Make sure that you are Debugging the application and not run it like "Run As..."
Considering that you are using Eclipse, Run -> Debug As -> <-Your Target Application->
Also make sure that where ever you have added breakpoints, those lines are reachable.
I've hit problems with IntelliJ debugging not hitting breakpoints before. You may have luck disabling the JUnit plugin and restarting IDEA.

Why is IntelliJ skipping breakpoints while remotely debugging

I have been asked to debug a Java application installed in Apache Karaf (OSGi) running in a VM hosted on my dev machine. My colleague has been able to do remote debugging successfully using Eclipse. My tool of choice is IntelliJ and in my attempts to debug remotely, IntelliJ connects successfully (via socket). If I pause the debugging session, the Karaf console freezes as expected and resumes when I click continue. But when I am paused I can see the following message in IntelliJ and my breakpoints are ignored.
Target VM is not paused by breakpoint request. Evaluation of methods is not possible in this mode.
What does this mean? I have searched and also gone through the documentation for IntelliJ. Why can Eclipse allow working breakpoints and IntelliJ doesn't?
Firstly, one presumes that you have started up your OSGI container (for example, Fuse Fabric) in debug mode. Often this is done by adding the argument debug to the start script.
For example:
c:\> startfabric.bat debug
As Tim noted, you just now need to make sure that your source code is exactly synced with whatever is deployed to the OSGI container.
To be sure, check out the exact same source code version as what is deployed to the server, and choose Build -> Rebuild Project. If necessary, do a mvn clean install on your machine, and deploy a bundle / feature that you have built yourself - then you know that the code you have locally should exactly match what is deployed.
Lastly, check your debug panels in IntelliJ, and remove any Watch expressions that might be interfering whilst in debug mode.

is it possible to run gradle in live mode

In sbt there is a live mode, if I use sbt ~run, then every time a java source changed, it will reload automatically. playframework also support that so that when change a source code, we don't reload manually. For gradle, I am running spring boot, but need to shutdown it and then startup after change some code, even if I am using --daemon, it still need some manually work. Anyway to load the code automatically?
A live mode for Gradle is in the works but not currently available. Plugins such as spring-boot may of course provide their own solution.

Resources