Enable fork more when devtools is present
This commit improves the run goal to automatically fork the process when devtools is present and log a warning when fork has been disabled via configuration since devtools will not work on a non-forked process. We don't want devtools to kick in for integration tests so the logic has been placed in `RunMojo` requiring a couple of protected methods to override. Closes gh-5137
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.boot.maven.it</groupId>
|
||||
<artifactId>run-devtools</artifactId>
|
||||
<version>0.0.1.BUILD-SNAPSHOT</version>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<!-- Devtools cannot be added here but the project has the class
|
||||
that the code is looking for -->
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>@project.groupId@</groupId>
|
||||
<artifactId>@project.artifactId@</artifactId>
|
||||
<version>@project.version@</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<fork>false</fork>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.springframework.boot.devtools.restart;
|
||||
|
||||
/**
|
||||
* Only meant to make sure that the plugin considers that devtools
|
||||
* is present.
|
||||
*/
|
||||
public class Restarter {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
public class SampleApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("I haz been run");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import static org.junit.Assert.assertTrue
|
||||
|
||||
def file = new File(basedir, "build.log")
|
||||
assertTrue 'Devtools should have been detected', file.text.contains('Fork mode disabled, devtools will be disabled')
|
||||
assertTrue 'Application should have ran', file.text.contains("I haz been run")
|
||||
|
||||
@@ -140,7 +140,8 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
|
||||
|
||||
/**
|
||||
* Flag to indicate if the run processes should be forked. {@code fork } is
|
||||
* automatically enabled if an agent or jvmArguments are specified.
|
||||
* automatically enabled if an agent or jvmArguments are specified, or if
|
||||
* devtools is present.
|
||||
* @since 1.2
|
||||
*/
|
||||
@Parameter(property = "fork")
|
||||
@@ -160,23 +161,6 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
|
||||
@Parameter(defaultValue = "false")
|
||||
private boolean skip;
|
||||
|
||||
/**
|
||||
* Specify if the application process should be forked.
|
||||
* @return {@code true} if the application process should be forked
|
||||
*/
|
||||
protected boolean isFork() {
|
||||
return (Boolean.TRUE.equals(this.fork)
|
||||
|| (this.fork == null && (hasAgent() || hasJvmArgs())));
|
||||
}
|
||||
|
||||
private boolean hasAgent() {
|
||||
return (this.agent != null && this.agent.length > 0);
|
||||
}
|
||||
|
||||
private boolean hasJvmArgs() {
|
||||
return (this.jvmArguments != null && this.jvmArguments.length() > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||
if (this.skip) {
|
||||
@@ -187,6 +171,32 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
|
||||
run(startClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify if the application process should be forked.
|
||||
* @return {@code true} if the application process should be forked
|
||||
*/
|
||||
protected boolean isFork() {
|
||||
return (Boolean.TRUE.equals(this.fork)
|
||||
|| (this.fork == null && enableForkByDefault()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify if fork should be enabled by default.
|
||||
* @return {@code true} if fork should be enabled by default
|
||||
* @see #logDisabledFork()
|
||||
*/
|
||||
protected boolean enableForkByDefault() {
|
||||
return hasAgent() || hasJvmArgs();
|
||||
}
|
||||
|
||||
private boolean hasAgent() {
|
||||
return (this.agent != null && this.agent.length > 0);
|
||||
}
|
||||
|
||||
private boolean hasJvmArgs() {
|
||||
return (this.jvmArguments != null && this.jvmArguments.length() > 0);
|
||||
}
|
||||
|
||||
private void findAgent() {
|
||||
try {
|
||||
if (this.agent == null || this.agent.length == 0) {
|
||||
@@ -221,17 +231,26 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
|
||||
doRunWithForkedJvm(startClassName);
|
||||
}
|
||||
else {
|
||||
if (hasAgent()) {
|
||||
getLog().warn("Fork mode disabled, ignoring agent");
|
||||
}
|
||||
if (hasJvmArgs()) {
|
||||
getLog().warn("Fork mode disabled, ignoring JVM argument(s) ["
|
||||
+ this.jvmArguments + "]");
|
||||
}
|
||||
logDisabledFork();
|
||||
runWithMavenJvm(startClassName, resolveApplicationArguments().asArray());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (hasAgent()) {
|
||||
getLog().warn("Fork mode disabled, ignoring agent");
|
||||
}
|
||||
if (hasJvmArgs()) {
|
||||
getLog().warn("Fork mode disabled, ignoring JVM argument(s) ["
|
||||
+ this.jvmArguments + "]");
|
||||
}
|
||||
}
|
||||
|
||||
private void doRunWithForkedJvm(String startClassName)
|
||||
throws MojoExecutionException, MojoFailureException {
|
||||
List<String> args = new ArrayList<String>();
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.boot.maven;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.List;
|
||||
|
||||
@@ -41,6 +42,26 @@ public class RunMojo extends AbstractRunMojo {
|
||||
|
||||
private static final int EXIT_CODE_SIGINT = 130;
|
||||
|
||||
private static final String RESTARTER_CLASS_LOCATION = "org/springframework/boot/devtools/restart/Restarter.class";
|
||||
|
||||
/**
|
||||
* Devtools presence flag to avoid checking for it several times per execution.
|
||||
*/
|
||||
private Boolean hasDevtools;
|
||||
|
||||
@Override
|
||||
protected boolean enableForkByDefault() {
|
||||
return super.enableForkByDefault() || hasDevtools();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void logDisabledFork() {
|
||||
super.logDisabledFork();
|
||||
if (hasDevtools()) {
|
||||
getLog().warn("Fork mode disabled, devtools will be disabled");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runWithForkedJvm(List<String> args) throws MojoExecutionException {
|
||||
try {
|
||||
@@ -92,6 +113,24 @@ public class RunMojo extends AbstractRunMojo {
|
||||
while (hasNonDaemonThreads);
|
||||
}
|
||||
|
||||
private boolean hasDevtools() {
|
||||
if (this.hasDevtools == null) {
|
||||
this.hasDevtools = checkForDevtools();
|
||||
}
|
||||
return this.hasDevtools;
|
||||
}
|
||||
|
||||
private boolean checkForDevtools() {
|
||||
try {
|
||||
URL[] urls = getClassPathUrls();
|
||||
URLClassLoader classLoader = new URLClassLoader(urls);
|
||||
return (classLoader.findResource(RESTARTER_CLASS_LOCATION) != null);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class RunProcessKiller implements Runnable {
|
||||
|
||||
private final RunProcess runProcess;
|
||||
|
||||
@@ -128,7 +128,7 @@ 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' or 'agent' options are specified.
|
||||
'jvmArguments' or 'agent' options are specified, or if devtools is present.
|
||||
|
||||
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}}
|
||||
@@ -164,7 +164,7 @@ spring.devtools.remote.restart.enabled=false
|
||||
---
|
||||
|
||||
Prior to <<<devtools>>>, the plugin supported hot refreshing of resources by default which has
|
||||
now be disabled in favor of the solution described above. You can restore it at any time by
|
||||
now be disabled in favour of the solution described above. You can restore it at any time by
|
||||
configuring your project:
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user