New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring-boot process not closing when running in debug mode from IntelliJ #1138

Closed
asolanaruiz opened this Issue Jun 23, 2014 · 19 comments

Comments

Projects
None yet
8 participants
@asolanaruiz

This is something that started happening after I upgraded to 1.1.1.RELEASE with 1.0.2.RELEASE I don't have that problem.

When I run spring boot in debug mode from IntelliJ (OSX 10.9.3) using IntelliJ's maven run configuration with the spring-boot:run goal, I'm not able to close the application.
Clicking the 'stop' button will apparently stop the application but it doesn't. IntelliJ thinks that it's not running anymore but I'm able to access the urls like if the application was running.
If I look at the processes running in my machine I see that the application is running and the only way to stop it is killing the process.

Thank you

@dsyer

This comment has been minimized.

Show comment
Hide comment
@dsyer

dsyer Jun 24, 2014

Member

The maven plugin changed in 1.1 to launch a new process and the IntelliJ guys haven't caught up yet. Why don't you just right click on the main class and debug it?

Member

dsyer commented Jun 24, 2014

The maven plugin changed in 1.1 to launch a new process and the IntelliJ guys haven't caught up yet. Why don't you just right click on the main class and debug it?

@asolanaruiz

This comment has been minimized.

Show comment
Hide comment
@asolanaruiz

asolanaruiz Jun 25, 2014

Thanks for you answer. Which main class are you referring to? The SpringBootServletInitializer?

Thanks for you answer. Which main class are you referring to? The SpringBootServletInitializer?

@dsyer

This comment has been minimized.

Show comment
Hide comment
@dsyer

dsyer Jun 27, 2014

Member

That depends. It's usually your own main() method (see for example all the samples in Spring Boot or the GS guides on spring.io).

Member

dsyer commented Jun 27, 2014

That depends. It's usually your own main() method (see for example all the samples in Spring Boot or the GS guides on spring.io).

@markfisher markfisher added this to the 1.1.4 milestone Jul 3, 2014

@markfisher markfisher closed this Jul 3, 2014

@markfisher markfisher reopened this Jul 3, 2014

@philwebb philwebb removed this from the 1.1.4 milestone Jul 3, 2014

@asolanaruiz

This comment has been minimized.

Show comment
Hide comment
@asolanaruiz

asolanaruiz Jul 14, 2014

I haven't been able to see anything wrong in the code. Maybe it's a problem with IntelliJ.

I haven't been able to see anything wrong in the code. Maybe it's a problem with IntelliJ.

@dsyer

This comment has been minimized.

Show comment
Hide comment
@dsyer

dsyer Jul 15, 2014

Member

I don't think it's a problem with IntelliJ, except that maybe they could add a feature to make it easier for you to do yet right thing. Having said that, I don't know what could be easier than running a vanilla main() method, so really you ought to be able to do that (like all the other IntelliJ users).

Member

dsyer commented Jul 15, 2014

I don't think it's a problem with IntelliJ, except that maybe they could add a feature to make it easier for you to do yet right thing. Having said that, I don't know what could be easier than running a vanilla main() method, so really you ought to be able to do that (like all the other IntelliJ users).

@asolanaruiz

This comment has been minimized.

Show comment
Hide comment
@asolanaruiz

asolanaruiz Jul 15, 2014

Thanks for your answer.
My current main method is really simple it's just this:

public static void main(String[] args) {
        SpringApplication.run(new Object[] {AppServletInitializer.class, ServletContainerConfig.class, ServletWebMvcConfig.class, AppConfig.class, SecurityConfig.class}, args);
}

Thanks for your answer.
My current main method is really simple it's just this:

public static void main(String[] args) {
        SpringApplication.run(new Object[] {AppServletInitializer.class, ServletContainerConfig.class, ServletWebMvcConfig.class, AppConfig.class, SecurityConfig.class}, args);
}
@dsyer

This comment has been minimized.

Show comment
Hide comment
@dsyer

dsyer Jul 16, 2014

Member

That's great. It should work fine. Just forget about maven, right click in that class, and see what the options are. If one of them is "Run" or "Debug" you are in business.

Member

dsyer commented Jul 16, 2014

That's great. It should work fine. Just forget about maven, right click in that class, and see what the options are. If one of them is "Run" or "Debug" you are in business.

@asolanaruiz

This comment has been minimized.

Show comment
Hide comment
@asolanaruiz

asolanaruiz Jul 17, 2014

I see what you mean. I'll try if I can debug the app like that, right now it throws a ClassNotFoundException so maybe I have to play with the application dependencies.

I see what you mean. I'll try if I can debug the app like that, right now it throws a ClassNotFoundException so maybe I have to play with the application dependencies.

@drdamour

This comment has been minimized.

Show comment
Hide comment
@drdamour

drdamour Aug 15, 2014

I also get the ClassNotFoundException when trying to debug the main method

Exception in thread "main" java.lang.IllegalStateException: Could not evaluate condition owing to internal class not found. This can happen if you are @ComponentScanning a springframework package (e.g. if you put a @componentscan in the default package by mistake)

@EnableAutoConfiguration
@ComponentScan
public class Commerce2APIApplication {

    public Commerce2APIApplication(){ // NOSONAR this isn't a utility class..and boot needs a public default constructor

    }

    public static void main(String[] args) {
        SpringApplication.run(Commerce2APIApplication.class, args);
    }

}

why was this forking done...it's such a pain in the butt to work around

I also get the ClassNotFoundException when trying to debug the main method

Exception in thread "main" java.lang.IllegalStateException: Could not evaluate condition owing to internal class not found. This can happen if you are @ComponentScanning a springframework package (e.g. if you put a @componentscan in the default package by mistake)

@EnableAutoConfiguration
@ComponentScan
public class Commerce2APIApplication {

    public Commerce2APIApplication(){ // NOSONAR this isn't a utility class..and boot needs a public default constructor

    }

    public static void main(String[] args) {
        SpringApplication.run(Commerce2APIApplication.class, args);
    }

}

why was this forking done...it's such a pain in the butt to work around

@philwebb

This comment has been minimized.

Show comment
Hide comment
@philwebb

philwebb Aug 15, 2014

Member

@drdamour is your Commerce2APIApplication class in a package? As mentioned in the exception, if it's not your entire classpath is scanned which can cause these problems.

Member

philwebb commented Aug 15, 2014

@drdamour is your Commerce2APIApplication class in a package? As mentioned in the exception, if it's not your entire classpath is scanned which can cause these problems.

@drdamour

This comment has been minimized.

Show comment
Hide comment
@drdamour

drdamour Aug 15, 2014

yes it's in a package...the problem is that i am packaging as a war, and so i'm setting spring-boot-starter-tomcat to scope of provided in my pom and thus main can't find stuff.

I've made a maven profile to toggle the scope of that package...i guess it's the best i can do.

<profile>
            <id>IDE Debug</id>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                    <scope>compile</scope>
                </dependency>
            </dependencies>
        </profile>

it's a shame how the fork breaks so many common maven/ide conventions. The maven menu is mostly useless now for spring-boot tasks. IntelliJ's run maven configurations are also useless.

anything triggered by spring-boot:run (like the git info stuff) is now a pain. The entire maven pipeline is being subverted by running main directly.

yes it's in a package...the problem is that i am packaging as a war, and so i'm setting spring-boot-starter-tomcat to scope of provided in my pom and thus main can't find stuff.

I've made a maven profile to toggle the scope of that package...i guess it's the best i can do.

<profile>
            <id>IDE Debug</id>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                    <scope>compile</scope>
                </dependency>
            </dependencies>
        </profile>

it's a shame how the fork breaks so many common maven/ide conventions. The maven menu is mostly useless now for spring-boot tasks. IntelliJ's run maven configurations are also useless.

anything triggered by spring-boot:run (like the git info stuff) is now a pain. The entire maven pipeline is being subverted by running main directly.

@philwebb

This comment has been minimized.

Show comment
Hide comment
@philwebb

philwebb Aug 15, 2014

Member

I'm afraid I'm not a IntelliJ user so I might be missing some context. You're saying that IntelliJ will let you run the bootRun task via Maven directly from the IDE? So your usual workflow is write some code, then trigger bootRun from IntelliJ to test it? You prefer working this way because there are steps in the maven pipeline that you always want to run, and these don't happen if you just launch the application directly? With earlier versions of Spring Boot this worked fine, but the change to the maven plugin to fork a new process for bootRun (#648) is causing issues? Provided scoped libraries are not being found?

Do you have time to put together a sample project and provide some instructions about how to replicate the issue (include things such as the IntelliJ version). Perhaps we can add a property to disable forking, or perhaps we just need to add a few more jars to the classpath when we fork.

Member

philwebb commented Aug 15, 2014

I'm afraid I'm not a IntelliJ user so I might be missing some context. You're saying that IntelliJ will let you run the bootRun task via Maven directly from the IDE? So your usual workflow is write some code, then trigger bootRun from IntelliJ to test it? You prefer working this way because there are steps in the maven pipeline that you always want to run, and these don't happen if you just launch the application directly? With earlier versions of Spring Boot this worked fine, but the change to the maven plugin to fork a new process for bootRun (#648) is causing issues? Provided scoped libraries are not being found?

Do you have time to put together a sample project and provide some instructions about how to replicate the issue (include things such as the IntelliJ version). Perhaps we can add a property to disable forking, or perhaps we just need to add a few more jars to the classpath when we fork.

@drdamour

This comment has been minimized.

Show comment
Hide comment
@drdamour

drdamour Aug 15, 2014

You're saying that IntelliJ will let you run the bootRun task via Maven directly from the IDE?

yes, there's a maven menu
there are also maven configurations available that give you more control over things

So your usual workflow is write some code, then trigger bootRun from IntelliJ to test it?

Yup

You prefer working this way because there are steps in the maven pipeline that you always want to run, and these don't happen if you just launch the application directly?

Yeah, i like having all the test run and git info plugin before start
Also intellij attaches a debugger to the goal as needed (when you invoke the debug option for the maven goal) but it doesn't know to attach to the forked process. IntelliJ changes the debug port randomly (so you can have multiple debug sessions).

With earlier versions of Spring Boot this worked fine, but the change to the maven plugin to fork a new process for bootRun (#648) is causing issues?

Yes, for example when you stop the process, the forked process doesn't stop.

Provided scoped libraries are not being found?

Yeah, if they are provided intellij doesn't have them on the class path when you do a run or debug configuration. I was guessing that the spring-boot:run task was doing some magic to get them on the classpath. This is a bit of a black box to me though

I don't have time right now to setup an example. Any existing project exhibits the basic behaviours. Any project that is packaged as war exhibits the class not found behaviour. I'm on latest IntelliJ 13.1.4, but this would be problem for a few versions back.

You're saying that IntelliJ will let you run the bootRun task via Maven directly from the IDE?

yes, there's a maven menu
there are also maven configurations available that give you more control over things

So your usual workflow is write some code, then trigger bootRun from IntelliJ to test it?

Yup

You prefer working this way because there are steps in the maven pipeline that you always want to run, and these don't happen if you just launch the application directly?

Yeah, i like having all the test run and git info plugin before start
Also intellij attaches a debugger to the goal as needed (when you invoke the debug option for the maven goal) but it doesn't know to attach to the forked process. IntelliJ changes the debug port randomly (so you can have multiple debug sessions).

With earlier versions of Spring Boot this worked fine, but the change to the maven plugin to fork a new process for bootRun (#648) is causing issues?

Yes, for example when you stop the process, the forked process doesn't stop.

Provided scoped libraries are not being found?

Yeah, if they are provided intellij doesn't have them on the class path when you do a run or debug configuration. I was guessing that the spring-boot:run task was doing some magic to get them on the classpath. This is a bit of a black box to me though

I don't have time right now to setup an example. Any existing project exhibits the basic behaviours. Any project that is packaged as war exhibits the class not found behaviour. I'm on latest IntelliJ 13.1.4, but this would be problem for a few versions back.

@ravshansbox

This comment has been minimized.

Show comment
Hide comment
@ravshansbox

ravshansbox Sep 6, 2014

running spring-boot:run has an advantage: when i declare spring-loaded as plugin dependency it will attach it and i will have ability to reload my class enhancements at runtime.

running spring-boot:run has an advantage: when i declare spring-loaded as plugin dependency it will attach it and i will have ability to reload my class enhancements at runtime.

@snicoll

This comment has been minimized.

Show comment
Hide comment
@snicoll

snicoll Sep 6, 2014

Member

You can do that from the IDE as well. Just add the relevant VM options, something like:

-javaagent:/path/to/spring-loaded.jar -noverify
Member

snicoll commented Sep 6, 2014

You can do that from the IDE as well. Just add the relevant VM options, something like:

-javaagent:/path/to/spring-loaded.jar -noverify
@dsyer

This comment has been minimized.

Show comment
Hide comment
@dsyer

dsyer Sep 6, 2014

Member

True (although it's a pain to have to remember the agent location).

The bottom line I think, is that unless IntelliJ gets smart about this and recognize that the process has forked, there's no way to have your Maven workflow and spring loaded agent attach from the IDE.

The forking behaviour was added precisely to support spring loaded, so if we add the option not to fork, it wouldn't work with agent attach.

Member

dsyer commented Sep 6, 2014

True (although it's a pain to have to remember the agent location).

The bottom line I think, is that unless IntelliJ gets smart about this and recognize that the process has forked, there's no way to have your Maven workflow and spring loaded agent attach from the IDE.

The forking behaviour was added precisely to support spring loaded, so if we add the option not to fork, it wouldn't work with agent attach.

@ravshansbox

This comment has been minimized.

Show comment
Hide comment
@ravshansbox

ravshansbox Sep 6, 2014

dsyer, I completely understand you and i was thinking it that way, but is there any way to inform intellij idea guys to work on the issue?

dsyer, I completely understand you and i was thinking it that way, but is there any way to inform intellij idea guys to work on the issue?

@axotna

This comment has been minimized.

Show comment
Hide comment
@axotna

axotna Nov 30, 2014

@dsyer not everyone needs spring loaded. But that definitely broke the usual workflow for us. We downgraded the plugin to 1.0.1 for this reason. All our saved "Run Configurations" in debug mode no longer reacted on breakpoints past 1.0.1. This costed business money. I am sorry but this was very frustrating and time wasting to figure out.

axotna commented Nov 30, 2014

@dsyer not everyone needs spring loaded. But that definitely broke the usual workflow for us. We downgraded the plugin to 1.0.1 for this reason. All our saved "Run Configurations" in debug mode no longer reacted on breakpoints past 1.0.1. This costed business money. I am sorry but this was very frustrating and time wasting to figure out.

@dsyer

This comment has been minimized.

Show comment
Hide comment
@dsyer

dsyer Nov 30, 2014

Member

The default behaviour should have changed with #1412. I'm not even sure why this issue is still open. Did you try upgrading instead?

Member

dsyer commented Nov 30, 2014

The default behaviour should have changed with #1412. I'm not even sure why this issue is still open. Did you try upgrading instead?

@dsyer dsyer added this to the 1.2.0 milestone Dec 1, 2014

@dsyer dsyer closed this Dec 1, 2014

@philwebb philwebb removed this from the 1.2.0 milestone Dec 1, 2014

philwebb referenced this issue Dec 20, 2014

Fix Maven Spring Loaded detection logic
Ensure that the Maven plugin RunMojo attempts to detect the Spring
Loaded agent before deciding if the JVM should be forked.

Fixes gh-2140
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment