EDIT: it does not work anymore from Spring Boot 3+. See Ruik's comment
tldr: You can try tweaking the command line like this:
spring-boot:run -Dspring-boot.run.fork=false
Explanation:
When running the application in debug mode, the IntelliJ debugger attaches to the Java process that it starts itself (by appending the appropriate parameters, -agentlib:jdwp etc, to the Java command line).
Quite often, these Java processes might then fork a new instance, which is not getting the same parameters, and because it is in a separate process, is not connected to the debugger. This can be confusing.
The spring-boot:run Maven goal, in addition to forking a new JVM, creates even more confusion, because it sometimes does fork and sometimes doesn't, depending on the options it gets, among other things. Some of this can be found in the documentation, but it's not always obvious.
You should first check whether the Java process actually is being debugged at all. When you start the application from IntelliJ, you will see messages scrolling by in the Run / Debug tab. At the top, there's the command line that is being executed. It should contain the debugger parameters (-agentlib:jdwp etc) and it should be followed by a message saying "Connected to the target VM", which is the debugger confirming that it has contact.
Next, if you are unsure if the JVM has been forked, you can check the process list in your OS, for example under MacOS and *nix you can use ps aux | grep java. The Java processes typically have a giant parameter list, most of which is the class path. The actual application being run is at the very end of the command line. If the JVM was forked, you have the process running the Maven goal, and another one running the Spring application. Then your debugger will be connected to the process you are not interested in, and your breakpoints won't work.
To stop spring-boot:run from forking, you can use the fork parameter above.
EDIT: it does not work anymore from Spring Boot 3+. See Ruik's comment
tldr: You can try tweaking the command line like this:
spring-boot:run -Dspring-boot.run.fork=false
Explanation:
When running the application in debug mode, the IntelliJ debugger attaches to the Java process that it starts itself (by appending the appropriate parameters, -agentlib:jdwp etc, to the Java command line).
Quite often, these Java processes might then fork a new instance, which is not getting the same parameters, and because it is in a separate process, is not connected to the debugger. This can be confusing.
The spring-boot:run Maven goal, in addition to forking a new JVM, creates even more confusion, because it sometimes does fork and sometimes doesn't, depending on the options it gets, among other things. Some of this can be found in the documentation, but it's not always obvious.
You should first check whether the Java process actually is being debugged at all. When you start the application from IntelliJ, you will see messages scrolling by in the Run / Debug tab. At the top, there's the command line that is being executed. It should contain the debugger parameters (-agentlib:jdwp etc) and it should be followed by a message saying "Connected to the target VM", which is the debugger confirming that it has contact.
Next, if you are unsure if the JVM has been forked, you can check the process list in your OS, for example under MacOS and *nix you can use ps aux | grep java. The Java processes typically have a giant parameter list, most of which is the class path. The actual application being run is at the very end of the command line. If the JVM was forked, you have the process running the Maven goal, and another one running the Spring application. Then your debugger will be connected to the process you are not interested in, and your breakpoints won't work.
To stop spring-boot:run from forking, you can use the fork parameter above.
The only approach that worked for me, is running or debugging application directly from Intellij Idea. Just open class which contains
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
And click right mouse button->Debug my application
Videos
Running a Spring Boot project from Maven with a specific profile
mvn spring-boot:run -Dspring-boot.run.profiles=foo,bar
Or by using a shell variable
SPRING_PROFILES_ACTIVE=foo mvn spring-boot:run
Or by passing arguments to the JVM
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Dspring.profiles.active=foo,bar"
These are the only methods that I know of that work for Spring Boot v2.0+.
The first option is recognized by the Spring Boot Maven plugin and passes it on to the application JVM.
Since version 2.0 of Spring Boot, the run goal forks the process by default. Since -Dspring.profiles.active is not recognized by the plugin directly, it's only seen by the Maven process and not passed on to the app itself. This is why it doesn't work in the form mvn spring-boot:run -Dspring.profiles.active=foo,bar.
In the second option, the shell variable should be visible to any subprocesses spawned from that shell.
Starting a Spring Boot project in debug mode from Maven
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"
Putting it together
mvn spring-boot:run -Dspring-boot.run.profiles=foo,bar -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"
Alternative, passing all arguments to JVM
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005 -Dspring.profiles.active=foo,bar"
The Maven pom.xml should include the Spring Boot plugin
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.1.RELEASE</version>
</plugin>
In IntelliJ you should create a new "Remote" debug configuration from the "Run/Debug Configurations" tool window. You'll find it in the main menu - "Run / Edit Configurations..."
The default config will use the same 5005 port.
After that, launch that debug config. The console should display "Connected to the target VM...".
Sources:
- https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/maven-plugin/examples/run-profiles.html
- https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/maven-plugin/examples/run-debug.html
If you're running from maven, then add the following parameters:
mvn spring-boot:run -Dspring.profiles.active=dev -Drun.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5555"
Here 5555 is a debug port number (you can use any other unoccupied port).
Then in IntelliJ you can use Remote Debug configuration and connect to that port.
If you open the pom.xml from intelliJ, you can create a Run Configuration with --spring.profiles.active=dev and main class that is a class with method main just like in a regular the most simple java application.
Option 3 seems to work, starting the maven goal in a separate terminal.
pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<jvmArguments>
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
</jvmArguments>
</configuration>
</plugin>
</plugins>
</build>
Terminal:
PS> mvn spring-boot:run -f .\pom.xml
# ...
[INFO] Attaching agents: []
Listening for transport dt_socket at address: 5005
IntelliJ IDEA:
- Create a Remote debug configuration
- Set the port number to match that entered in the pom.xml (e.g.
5005) - Run the maven goal in a terminal.
- It appears to wait for a debug connection on the port before starting the Spring Boot application
- Run the Remote debug configuration in IntelliJ IDEA.
- When it connects to the "remote" port, the Spring Boot application will start up and break points will be hit in the IDE.
I finally found at least a workaround. May not be ideal in every cases.
I do a @SpringBootTest with JUnit and then a test method that just sleeps for one our. That way the Spring Context comes up and stays for debugging. If I let Spring bind to a defined port I can even call REST endpoints.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
class TemplateApplicationTests {
@Test
void contextLoads() throws InterruptedException {
Thread.sleep(360000);
}
}
In your Run/Debug Configurations enter the following into your command line:
spring-boot:run -Dspring.profiles.active=local,<mine> -Dfork=false -f pom.xml
My Maven spring-boot:run configuration debugs just fine with the -D fork=false added.
You may use below command in the CLI:
export MAVEN_OPTS="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n
Below is my project settings:
enter image description here