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: ---