-
Notifications
You must be signed in to change notification settings - Fork 41.2k
Add "start-stop" goals for the spring-boot-maven-plugin #2525
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
Comments
This would definitely be helpful. |
i am having exactly the same problem. +1 |
From what I can see, forking will be hard (thought not impossible) to support. I've been looking for various ways to do this and the JMX route seems the cleanest. The process that starts the application pass an extra internal property that will register an MBean on the platform mbean server (the mbean server of the current VM). Stop will use that reference to request the context to gracefully shutdown. This works fine but now we have another problem: since we are invoking a main method, we have no good way to know that the application has started. Surely |
Looks like that using JMX to figure out if the app is running is a good choice as well. Trying that. |
SpringApplicationLifecycle provides lifecycle operations on the current Spring Boot application. It can be registered to the mBean server of the current platform if a specific property is set. The Maven plugin uses that lifecycle to trigger a proper shutdown of the application. See spring-projectsgh-2525
This is an attempt at finalizing the feature defined in spring-projectsgh-2525. Including fork support brought a lot of complexity for no good reason and right now the Maven process is unable to connect to the MBean server of a different process for no good reason. jconsole can connect just fine and the same code works "in-process".
SpringApplicationLifecycle provides lifecycle operations on the current Spring Boot application. It can be registered to the platform mBean server of the if a specific property is set. Besides, the JMX name can also be customized via a property in case more than one Spring Boot application is started in the same process. The Maven plugin uses that MBean to check that the application is ready before ending the "start" phase. It uses it to trigger a proper shutdown of the application during the "stop" phase. Such change permits the maven plugin to integrate a classical integration test scenario where the "start" goal is invoked during the pre-integration phase and the "stop" goal during the post-integration phase. See spring-projectsgh-2525
okay so those who are interested to try this out are welcome to use a local build of my gh-2525 branch branch. This should work out-of-the-box as long as forking is not enabled (more on that later). For instance, the following configuration should run your integration tests <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>pre-integration-test</id>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>post-integration-test</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
<configuration>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18.1</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build> We are using a property to trigger an auto-configuration that registers a MBean who serves two purposes:
So what's the problem with fork? The short answer is that I don't know. Since we are using JMX, we can also start the process with the necessary system properties to expose the MbeanServer on a given port and connect to that port to invoke the exact same operations. But for some reasons it does not work while the same code outside of the maven plugin works. I am sure I am missing something. If you want to try it out (code unpolished), check the gh-2525-remote. |
Nice, I just got this working. I did have to make SpringApplicationLifecycleAutoConfiguration public because I am not using @EnableAutoConfiguration. I hope you can consider that change. I'll provide more feedback once I implement more integration tests. |
Yes, I intend to reuse that for something else actually (windows service that can start/stop a boot app). Can you share a bit more about your use case? (why you're not using auto-config I mean). Thanks for testing! |
I'm on an earlier version of spring boot (1.1.8) and I recall needing spring-mvc, which in turn brought in the freemarker dependency. I don't actually have any freemarker templates, so the application would complain that it could not find the template location. I would have to add spring.freemarker.checkTemplateLocation=false to the properties. Instead I removed @EnableAutoConfiguration and used just the AutoConfiguration classes I needed. |
I would strongly advise you to restore to a proper use of the auto-configuration. All those hacks for a property change seems a bit extreme to me. Anyway, we won't backport that code in 1.1.x |
I'll be upgrading to the latest soon. Thanks. |
SpringApplicationLifecycle provides lifecycle operations on the current Spring Boot application. It can be registered to the platform mBean server of the if a specific property is set. Besides, the JMX name can also be customized via a property in case more than one Spring Boot application is started in the same process. The Maven plugin uses that MBean to check that the application is ready before ending the "start" phase. It uses it to trigger a proper shutdown of the application during the "stop" phase. Such change permits the maven plugin to integrate a classical integration test scenario where the "start" goal is invoked during the pre-integration phase and the "stop" goal during the post-integration phase. See spring-projectsgh-2525
Update the maven plugin to support forked process as well. If a forked process is required, the platform MBean Server is exposed using a configurable JMX port that is latter used to access the application. See spring-projectsgh-2525
Support for fork process has been added. |
@snicoll I've needed to revert this as there are a few kinks that I think we need to work though first. Can we move this is branch and iterate on it a little bit? Specifically these are my initial concerns: spring-boot-maven-testsWe've got into trouble before trying to use the SpringApplicationLifecycleAutoConfigurationThe lifecycle JMX stuff feels quite fundamental and I wonder if it would be better in Property passing in StartMojoUsing |
SpringApplicationLifecycle provides lifecycle operations on the current Spring Boot application. It can be registered as an MBean of the platform MBean server if a specific property is set. Besides, the JMX name can also be customized via a property in case more than one Spring Boot application is started in the same process. The Maven plugin uses that MBean to check that the application is ready before ending the "start" phase. It uses it to trigger a proper shutdown of the application during the "stop" phase. If the process has to be forked, the platform MBean server is exposed on a configurable port so that the maven plugin can connect to it. Such change permits the maven plugin to integrate a classical integration test scenario where the "start" goal is invoked during the pre-integration phase and the "stop" goal during the post-integration phase. Closes spring-projectsgh-2525
OK. I've created a new Regarding your concerns:
Let me know how you want to iterate on this. |
@snicoll Could I ask you to create a tag on gh-2525 branch? In this case I be able to build JAR via https://jitpack.io and test it. |
@php-coder you can fork my fork and create whatever tag you want :) That being said, I'd checkout and run a full build actually: this gives you I've been discussing this with @philwebb yesterday and I'll resume work on it this week still. We really want this to be part of 1.3.0.M1 that should be released soon. If you try this out, please report here, thanks! |
- Verify that isReady has been called - When forking, use a random port for JMX - Don’t wait for application termination as it introduces a race condition and verifying that shutdown has been requested is sufficient See gh-2525
Required to allow start/stop spring boot application. @see spring-projects/spring-boot#2525
Master rely on 4.2 snapshot so you have to use that, yes. |
Forget my last comment, please. I forgot to remove |
Finally, I've got it working! Thanks! |
👍 |
Could it be that the new functionality is broken at the moment? I had it running with these settings:
Here's the relevant section from my pom.xml: <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${springboot.version}</version> <executions> <execution> <id>pre-integration-test</id> <goals> <goal>start</goal> </goals> </execution> <execution> <id>post-integration-test</id> <goals> <goal>stop</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <configuration> <groups>integration</groups> <includes> <include>**/*.java</include> </includes> </configuration> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin> And the relevant annotations from my main class: @EnableAutoConfiguration @ComponentScan @ImportResource({ "classpath*:applicationContext.xml", "classpath*:handlers/*.xml" }) Now when I run 'mvn install', my tomcat application comes up and is functional (I can run the integration tests against it from the IDE while it's up), but the plugin fails to notice that it is up, so after a timeout I end up with this error: Spring application did not start before the configured timeout (30000ms -> [Help 1] With this very same setup my integration tests were still running one or two weeks ago. Am I doing something wrong? Or is there a problem with the current snapshots? |
It could have been broken this morning. Could you please try again with the current SNAPSHOT? |
Just tried again with a clean ~/.m2/repository, same problem. |
Nope, it's still broken. Thanks for the report! Follow #3124 for further updates |
(Y) |
The issue is fixed but you'll have to wait an hour to get a fresh snapshot with the fix. You can also build locally if you want. Thanks! |
👍 |
Required to allow start/stop spring boot application. @see spring-projects/spring-boot#2525
Required to allow start/stop spring boot application. @see spring-projects/spring-boot#2525
@php-coder hwo did you resolve the issue with GenericApplicationListener I am facing the same when upgrading to >1.3.0.M1 current pom is like
|
@gauravbrills you are forcing a Spring framework version yourself. Please note that It would be much better if you were not forcing these versions yourself. Can't you use the |
Thanks @snicoll ya done that also but still some 4.1.6 dependecy are coming in not sure why I think those are causing the issue .Let me check more |
If you can't trace it down please open a stackoverflow thread. Thanks. |
@snicoll it worked thanks .. using the BOM was a silly error from my side cheers . |
In order to run integration tests for a spring boot app, you can use the workaround described in #667.
There is a more detailed article here.
But in some cases, this approach can't be used. One example would be running Cucumber tests.
I have two use cases: The first one uses maven. I want to start my spring-boot app, run some Cucumber tests, then stop the spring-boot app, everything within Maven.
Another use case would be: Having the spring-boot running in my IDE and then run the Cucumber tests also from the IDE, by connecting to the already running app.
I wouldn't like to have the deployment phase hardcoded into the test class as in the example article. This is because (as described in the second use case) if I already have an instance of the application running, I should be able to run my cucumber test directly from my IDE, without starting another instance. I'd like to decouple the deployment step and testing step, as they don't really belong together.
Another reason for having the start-stop approach in the maven plugin is that the method of running the tests described in the article doesn't help me, because Cucumber has to be run using a
@RunWith(@Cucumber.class)
junit annotation, and the spring boot need the@RunWith(SpringJUnit4ClassRunner.class)
annotation. And we can't use two@RunWith
annotations on one test class.I managed to start my spring boot app using maven, like this:
But after the boot-app is started, the maven build is blocked... As soon as you press Ctrl+C, to stop the tomcat, the build resumes.
The text was updated successfully, but these errors were encountered: