Execution doesn't stop at breakpoints for 2.0.0.M5 applications when running gradle bootRun task in IntelliJ. It works fine with 1.5.8.RELEASE. Also, execution stops when running 2.0.0.M5 applications using main method. This is tested when using kotlin.
In Boot 1.5 the bootRun task extended the Gradle JavaExec class. In 2.0 we intentionally don't do that. Perhaps the change is messing with the way that IntelliJ does debugging.
I'm afraid there's probably not much we can do about it. I suggest you raise an issue with JetBrains.
@TheKojuEffect If you raise an issue with JetBrains, could you please add a link to it here?
I'm wondering if the advice from the Gradle team to stop extending JavaExec may not be such a good idea.
I'm pretty sure that the problem here is that the IDE now has no way of knowing that the task is going to fork a separate JVM or how to pass the debug arguments to that JVM. If we swapped back to extending JavaExec it would mean that implementing #1176 is significantly harder, if not impossible. We wouldn't be able to use @Option and @OptionValue to map the task's settings to the command line arguments. Raising this problem with the Gradle team is what prompted them to recommend that we don't subclass JavaExec.
I think we have two choices here:
JavaExec. This would fix the problem reported here but require us to give up on @Option and @OptionValue for implementing #1176.bootRun to be debugged, but would leave the door open for implementing #1176.@eriwen @bmuschko I'd appreciate your expertise here please. Is there anyway we can navigate out of this corner and keep the best of both worlds?
Issue raised for IntelliJ: https://youtrack.jetbrains.com/issue/IDEA-181659
@TheKojuEffect Could you please provide more information here?
debug property for the bootRun task?This is what I see. I guess it's because the task that wraps Project.javaexec does not expose a debug property:
Could not set unknown property 'debug' for task ':bootRun' of type org.springframework.boot.gradle.tasks.run.BootRun.
Before it was extending JavaExec which provides the debug property out-of-the-box.
Generally speaking, a sample project would be helpful.
Hi @bmuschko, I used IntelliJ gradle plugin's bootRun task to debug a simple project generated from start.spring.io with Spring Boot 2.0.0.M5.
@TheKojuEffect OK, thanks for answering my question on the sample project. Could you please also provide information on my other questions?
I think the answers to the other questions are already in this issue. As I understand it, those answers are:
How do you debug? What command line options are you providing to Gradle? Are you setting the debug property for the bootRun task?
The bootRun task is being debugged via IDEA's Gradle integration.
What exactly are you trying to debug? Your build script code, the Spring Boot code or your application code?
The application as launched by bootRun.
What error message are you seeing exactly with the milestone plugin?
There is no error message. The JVM that runs the application doesn't have debugging enabled so breakpoints in application code have no effect.
The
bootRuntask is being debugged via IDEA's Gradle integration.
Thanks for clarifying. I wasn't aware that you can debug directly from the Gradle integration in IntelliJ. Here's what I think is happening:
JavaExec then set the value of the property debug to true. If task is some other type then ignore.With the change from JavaExec to Project.javaexec(Closure) IntelliJ cannot identify the task as a JavaExec task anymore. Also the debug property doesn't exist and therefore debugging isn't propagated.
What I think needs to happen? Not sure if it will work though. It somewhat depends on how IntelliJ is determining the debugability of a task.
debug of type Boolean.Project.javaexec.I can look into providing a pull request sometime later this week.
Thanks, @bmuschko.
In addition to a debug property, I imagine it may also be necessary to provide properties for the port, whether or not the JVM suspends on launch, etc. All in all, I'm not keen on bootRun becoming an unusual task that IDEs have to recognise, rather than a specialisation of JavaExec that can just take advantage of whatever functionality already exists.
To avoid an unwanted burden on IDE developers, I think I'd prefer to revert BootRun to being a JavaExec subclass. That'll inhibit the implementation of #1176, but it feels like the least bad option.
/cc @YannCebron from JetBrains just in case he wants to convince me otherwise…
In addition to a debug property, I imagine it may also be necessary to provide properties for the port...
Yes, you'll want to expose the system properties as well for users to configure. By extending JavaExec you had those available by default. I personally still think that you are better off by not extending from JavaExec as you expose _all_ properties from JavaExec. Some properties should simply not be exposed to users e.g. the main class. I can't see why that wouldn't be hard-coded by the plugin. IMHO that's an implementation detail.
All in all, I'm not keen on bootRun becoming an unusual task that IDEs have to recognise...
It would be good to know how IntelliJ actually detects that a task is debuggable under the covers. To indicate such functionality I think we (as in Gradle engineers) should expose an interface that allows IDE developers to detect if a task is debuggable. Tasks should implement the interface as needed.
public interface Debuggable {
boolean isDebug();
void setDebug(boolean debug);
}
We're going to switch BootRun back to being a JavaExec subclass.
@wilkinsona I guess there's nothing really speaking against moving back to JavaExec except for exposing all properties available. Let me know if you need further assistance on that front.
Most helpful comment
I'm wondering if the advice from the Gradle team to stop extending
JavaExecmay not be such a good idea.I'm pretty sure that the problem here is that the IDE now has no way of knowing that the task is going to fork a separate JVM or how to pass the debug arguments to that JVM. If we swapped back to extending
JavaExecit would mean that implementing #1176 is significantly harder, if not impossible. We wouldn't be able to use@Optionand@OptionValueto map the task's settings to the command line arguments. Raising this problem with the Gradle team is what prompted them to recommend that we don't subclassJavaExec.I think we have two choices here:
JavaExec. This would fix the problem reported here but require us to give up on@Optionand@OptionValuefor implementing #1176.bootRunto be debugged, but would leave the door open for implementing #1176.@eriwen @bmuschko I'd appreciate your expertise here please. Is there anyway we can navigate out of this corner and keep the best of both worlds?