diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/run-devtools/pom.xml b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-devtools/pom.xml
new file mode 100644
index 0000000000..c56c0c0b4f
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-devtools/pom.xml
@@ -0,0 +1,33 @@
+
+
+ 4.0.0
+ org.springframework.boot.maven.it
+ run-devtools
+ 0.0.1.BUILD-SNAPSHOT
+
+ UTF-8
+
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+
+ package
+
+ run
+
+
+ false
+
+
+
+
+
+
+
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/run-devtools/src/main/java/org/springframework/boot/devtools/Restarter.java b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-devtools/src/main/java/org/springframework/boot/devtools/Restarter.java
new file mode 100644
index 0000000000..b39b4de899
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-devtools/src/main/java/org/springframework/boot/devtools/Restarter.java
@@ -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 {
+
+}
\ No newline at end of file
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/run-devtools/src/main/java/org/test/SampleApplication.java b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-devtools/src/main/java/org/test/SampleApplication.java
new file mode 100644
index 0000000000..3cf18b6ca3
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-devtools/src/main/java/org/test/SampleApplication.java
@@ -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");
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/run-devtools/verify.groovy b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-devtools/verify.groovy
new file mode 100644
index 0000000000..fa0ecade55
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-devtools/verify.groovy
@@ -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")
+
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java
index ca68f2e73b..ff3652eb8a 100644
--- a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java
@@ -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 args = new ArrayList();
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java
index 28f2c348e6..812106d739 100644
--- a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java
@@ -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 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;
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/usage.apt.vm b/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/usage.apt.vm
index f1b384e06a..4d819ee913 100644
--- a/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/usage.apt.vm
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/usage.apt.vm
@@ -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 <<>> parameter, see {{{./examples/run-debug.html}Debug the application}}
@@ -164,7 +164,7 @@ spring.devtools.remote.restart.enabled=false
---
Prior to <<>>, 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:
---