Fork application process with Maven by default

Closes gh-16945
pull/16972/head
Stephane Nicoll 6 years ago
parent 3432044997
commit a5537bd2e1

@ -829,8 +829,8 @@ and triggers a restart. In IntelliJ IDEA, building the project
====
As long as forking is enabled, you can also start your application by using the supported
build plugins (Maven and Gradle), since DevTools needs an isolated application
classloader to operate properly. By default, Gradle and Maven do that when they detect
DevTools on the classpath.
classloader to operate properly. By default, the Gradle and Maven plugins fork the
application process.
====

@ -22,9 +22,6 @@
<goals>
<goal>run</goal>
</goals>
<configuration>
<fork>true</fork>
</configuration>
</execution>
</executions>
</plugin>

@ -23,7 +23,6 @@
<goal>run</goal>
</goals>
<configuration>
<fork>true</fork>
<profiles>
<profile>foo</profile>
<profile>bar</profile>

@ -22,6 +22,9 @@
<goals>
<goal>run</goal>
</goals>
<configuration>
<fork>false</fork>
</configuration>
</execution>
</executions>
</plugin>

@ -1,61 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.boot.maven.it</groupId>
<artifactId>start-stop-automatic-fork</artifactId>
<version>0.0.1.BUILD-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>@java.version@</maven.compiler.source>
<maven.compiler.target>@java.version@</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>@build-helper-maven-plugin.version@</version>
<executions>
<execution>
<id>reserve-jmx-port</id>
<goals>
<goal>reserve-network-port</goal>
</goals>
<phase>process-resources</phase>
<configuration>
<portNames>
<portName>jmx.port</portName>
</portNames>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>@project.groupId@</groupId>
<artifactId>@project.artifactId@</artifactId>
<version>@project.version@</version>
<executions>
<execution>
<id>pre-integration-test</id>
<goals>
<goal>start</goal>
</goals>
<configuration>
<jvmArguments>-Dfoo=bar</jvmArguments>
</configuration>
</execution>
<execution>
<id>post-integration-test</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
<configuration>
<jmxPort>${jmx.port}</jmxPort>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -1,82 +0,0 @@
/*
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.test;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
/**
* This sample app simulates the JMX Mbean that is exposed by the Spring Boot application.
*/
public class SampleApplication {
private static final Object lock = new Object();
public static void main(String[] args) throws Exception {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName(
"org.springframework.boot:type=Admin,name=SpringApplication");
SpringApplicationAdmin mbean = new SpringApplicationAdmin();
mbs.registerMBean(mbean, name);
// Flag the app as ready
mbean.ready = true;
int waitAttempts = 0;
while (!mbean.shutdownInvoked) {
if (waitAttempts > 30) {
throw new IllegalStateException(
"Shutdown should have been invoked by now");
}
synchronized (lock) {
lock.wait(250);
}
waitAttempts++;
}
}
public interface SpringApplicationAdminMXBean {
boolean isReady();
void shutdown();
}
static class SpringApplicationAdmin implements SpringApplicationAdminMXBean {
private boolean ready;
private boolean shutdownInvoked;
@Override
public boolean isReady() {
System.out.println("isReady: " + this.ready);
return this.ready;
}
@Override
public void shutdown() {
this.shutdownInvoked = true;
System.out.println("Shutdown requested");
}
}
}

@ -1,5 +0,0 @@
import static org.junit.Assert.assertTrue
def file = new File(basedir, "build.log")
assertTrue 'Start should have waited for application to be ready', file.text.contains("isReady: true")
assertTrue 'Shutdown should have been invoked', file.text.contains("Shutdown requested")

@ -50,7 +50,6 @@
</execution>
</executions>
<configuration>
<fork>true</fork>
<jmxPort>${jmx.port}</jmxPort>
</configuration>
</plugin>

@ -30,6 +30,9 @@
</goals>
</execution>
</executions>
<configuration>
<fork>false</fork>
</configuration>
</plugin>
</plugins>
</build>

@ -75,8 +75,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
private boolean addResources = false;
/**
* Path to agent jar. NOTE: the use of agents means that processes will be started by
* forking a new JVM.
* Path to agent jar. NOTE: a forked process is required to use this feature.
* @since 1.0
* @deprecated since 2.2.0 in favor of {@code agents}
*/
@ -85,8 +84,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
private File[] agent;
/**
* Path to agent jars. NOTE: the use of agents means that processes will be started by
* forking a new JVM.
* Path to agent jars. NOTE: a forked process is required to use this feature.
* @since 2.2
*/
@Parameter(property = "spring-boot.run.agents")
@ -101,8 +99,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
/**
* Current working directory to use for the application. If not specified, basedir
* will be used. NOTE: the use of working directory means that processes will be
* started by forking a new JVM.
* will be used. NOTE: a forked process is required to use this feature.
* @since 1.5
*/
@Parameter(property = "spring-boot.run.workingDirectory")
@ -111,16 +108,15 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
/**
* JVM arguments that should be associated with the forked process used to run the
* application. On command line, make sure to wrap multiple values between quotes.
* NOTE: the use of JVM arguments means that processes will be started by forking a
* new JVM.
* NOTE: a forked process is required to use this feature.
* @since 1.1
*/
@Parameter(property = "spring-boot.run.jvmArguments")
private String jvmArguments;
/**
* List of JVM system properties to pass to the process. NOTE: the use of system
* properties means that processes will be started by forking a new JVM.
* List of JVM system properties to pass to the process. NOTE: a forked process is
* required to use this feature.
* @since 2.1
*/
@Parameter
@ -128,8 +124,8 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
/**
* List of Environment variables that should be associated with the forked process
* used to run the application. NOTE: the use of Environment variables means that
* processes will be started by forking a new JVM.
* used to run the application. NOTE: a forked process is required to use this
* feature.
* @since 2.1
*/
@Parameter
@ -177,13 +173,13 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
private File classesDirectory;
/**
* Flag to indicate if the run processes should be forked. {@code fork} is
* automatically enabled if an agent, jvmArguments or working directory are specified,
* or if devtools is present.
* Flag to indicate if the run processes should be forked. Disabling forking will
* disable some features such as an agent, custom JVM arguments, devtools or
* specifying the working directory to use.
* @since 1.2
*/
@Parameter(property = "spring-boot.run.fork")
private Boolean fork;
@Parameter(property = "spring-boot.run.fork", defaultValue = "true")
private boolean fork;
/**
* Flag to include the test classpath when running.
@ -213,15 +209,16 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
* @return {@code true} if the application process should be forked
*/
protected boolean isFork() {
return (Boolean.TRUE.equals(this.fork)
|| (this.fork == null && enableForkByDefault()));
return this.fork;
}
/**
* Specify if fork should be enabled by default.
* @return {@code true} if fork should be enabled by default
* @see #logDisabledFork()
* @deprecated as of 2.2.0 in favour of enabling forking by default.
*/
@Deprecated
protected boolean enableForkByDefault() {
return hasAgent() || hasJvmArgs() || hasEnvVariables()
|| hasWorkingDirectorySet();
@ -264,7 +261,6 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
/**
* Log a warning indicating that fork mode has been explicitly disabled while some
* conditions are present that require to enable it.
* @see #enableForkByDefault()
*/
protected void logDisabledFork() {
if (getLog().isWarnEnabled()) {
@ -273,9 +269,8 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
}
if (hasJvmArgs()) {
RunArguments runArguments = resolveJvmArguments();
getLog().warn("Fork mode disabled, ignoring JVM argument(s) [" + Arrays
.stream(runArguments.asArray()).collect(Collectors.joining(" "))
+ "]");
getLog().warn("Fork mode disabled, ignoring JVM argument(s) ["
+ String.join(" ", runArguments.asArray()) + "]");
}
if (hasWorkingDirectorySet()) {
getLog().warn(

@ -54,6 +54,7 @@ public class RunMojo extends AbstractRunMojo {
private Boolean hasDevtools;
@Override
@Deprecated
protected boolean enableForkByDefault() {
return super.enableForkByDefault() || hasDevtools();
}

@ -67,8 +67,7 @@ public class StartMojo extends AbstractRunMojo {
private String jmxName = SpringApplicationAdminClient.DEFAULT_OBJECT_NAME;
/**
* The port to use to expose the platform MBeanServer if the application needs to be
* forked.
* The port to use to expose the platform MBeanServer if the application is forked.
*/
@Parameter
private int jmxPort = 9001;

@ -6,10 +6,8 @@
2014-05-14
-----
By default, the <<<run>>> goal runs in the same process unless jvm arguments or an agent have been specified. You
can enable or disable forking explicitly using the <<<fork>>> attribute.
If you need to fork the process and debug it you can add the necessary JVM arguments to enable remote debugging. The
By default, the <<<run>>> goal runs your application in a forked process. If you need to
debug it, you should add the necessary JVM arguments to enable remote debugging. The
following configuration suspend the process until a debugger has joined on port 5005:
---
@ -38,8 +36,8 @@
</project>
---
Note that since you specified some JVM arguments, the process is forked automatically. These arguments can be
specified on the command line as well, make sure to wrap that properly, that is:
These arguments can be specified on the command line as well, make sure to wrap that
properly, that is:
---
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"

@ -130,10 +130,11 @@ Usage
mvn spring-boot:run
---
By default the application is executed directly from the Maven JVM. If you need to run
in a forked process you can use the 'fork' option. Forking will also occur if the
'jvmArguments', 'systemPropertyVariables', 'environmentVariables' or 'agent' options
are specified, or if devtools is present.
By default the application is executed in a forked process. Although this is not
recommended, it is possible to execute the application directly from the Maven JVM by
disabling the <<<fork>>> property. Doing so means that <<<jvmArguments>>>,
<<<systemPropertyVariables>>>, <<<environmentVariables>>> and <<<agent>>> options are
ignored.
If you need to specify some JVM arguments (i.e. for debugging purposes), you can use
the <<<jvmArguments>>> parameter, see {{{./examples/run-debug.html}Debug the application}}

Loading…
Cancel
Save