diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/integration-tests.adoc b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/integration-tests.adoc index 8dd219a1ae..c21404291b 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/integration-tests.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/integration-tests.adoc @@ -10,7 +10,8 @@ include::../maven/integration-tests/pom.xml[tags=integration-tests] Such setup can now use the https://maven.apache.org/surefire/maven-failsafe-plugin[failsafe-plugin] to run your integration tests as you would expect. -NOTE: By default, the application is started in a separate process and JMX is used to communicate with the application. +NOTE: The application is started in a separate process and JMX is used to communicate with the application. +By default, the plugin uses port `9001`. If you need to configure the JMX port, see <>. You could also configure a more advanced setup to skip the integration tests when a specific property has been set, see <>. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/running.adoc b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/running.adoc index 369b633ff2..e485a7400a 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/running.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/running.adoc @@ -15,9 +15,6 @@ There is also explicit support for <>. -Although this is not recommended (and deprecated), it is possible to execute the application directly from the Maven JVM by disabling the `fork` property. -Doing so means that the `jvmArguments`, `systemPropertyVariables`, `environmentVariables` and `agents` options are ignored. - Spring Boot `devtools` is a module to improve the development-time experience when working on Spring Boot applications. To enable it, just add the following dependency to your project: diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/RunIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/RunIntegrationTests.java index 823ce6bcbb..dd7ce477eb 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/RunIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/RunIntegrationTests.java @@ -44,22 +44,6 @@ class RunIntegrationTests { }); } - @TestTemplate - @Deprecated - void whenForkingIsDisabledAndDevToolsIsPresentDevToolsIsDisabled(MavenBuild mavenBuild) { - mavenBuild.project("run-devtools").goals("spring-boot:run").execute((project) -> assertThat(buildLog(project)) - .contains("I haz been run").contains("Fork mode disabled, devtools will be disabled")); - } - - @TestTemplate - @Deprecated - void whenForkingIsDisabledJvmArgumentsAndWorkingDirectoryAreIgnored(MavenBuild mavenBuild) { - mavenBuild.project("run-disable-fork").goals("spring-boot:run") - .execute((project) -> assertThat(buildLog(project)).contains("I haz been run").contains( - "Fork mode disabled, ignoring JVM argument(s) [-Dproperty1=value1 -Dproperty2 -Dfoo=bar]") - .contains("Fork mode disabled, ignoring working directory configuration")); - } - @TestTemplate void whenEnvironmentVariablesAreConfiguredTheyAreAvailableToTheApplication(MavenBuild mavenBuild) { mavenBuild.project("run-envargs").goals("spring-boot:run") @@ -104,13 +88,6 @@ class RunIntegrationTests { (project) -> assertThat(buildLog(project)).contains("I haz been run with profile(s) 'foo,bar'")); } - @TestTemplate - @Deprecated - void whenProfilesAreConfiguredAndForkingIsDisabledTheyArePassedToTheApplication(MavenBuild mavenBuild) { - mavenBuild.project("run-profiles-fork-disabled").goals("spring-boot:run").execute( - (project) -> assertThat(buildLog(project)).contains("I haz been run with profile(s) 'foo,bar'")); - } - @TestTemplate void whenUseTestClasspathIsEnabledTheApplicationHasTestDependenciesOnItsClasspath(MavenBuild mavenBuild) { mavenBuild.project("run-use-test-classpath").goals("spring-boot:run") diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/StartStopIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/StartStopIntegrationTests.java index 3ef33cdbe0..1ccee63552 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/StartStopIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/StartStopIntegrationTests.java @@ -32,13 +32,6 @@ import static org.assertj.core.api.Assertions.contentOf; @ExtendWith(MavenBuildExtension.class) class StartStopIntegrationTests { - @TestTemplate - @Deprecated - void startStopWithForkDisabledWaitsForApplicationToBeReadyAndThenRequestsShutdown(MavenBuild mavenBuild) { - mavenBuild.project("start-stop-fork-disabled").goals("verify").execute( - (project) -> assertThat(buildLog(project)).contains("isReady: true").contains("Shutdown requested")); - } - @TestTemplate void startStopWaitsForApplicationToBeReadyAndThenRequestsShutdown(MavenBuild mavenBuild) { mavenBuild.project("start-stop").goals("verify").execute( diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-devtools/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-devtools/pom.xml deleted file mode 100644 index 4f6bcd76fa..0000000000 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-devtools/pom.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - 4.0.0 - org.springframework.boot.maven.it - run-devtools - 0.0.1.BUILD-SNAPSHOT - - UTF-8 - @java.version@ - @java.version@ - - - - - - @project.groupId@ - @project.artifactId@ - @project.version@ - - false - - - - - diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java deleted file mode 100644 index 1b9c7813b3..0000000000 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2012-2020 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.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-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-devtools/src/main/java/org/test/SampleApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-devtools/src/main/java/org/test/SampleApplication.java deleted file mode 100644 index 94e5520be8..0000000000 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-devtools/src/main/java/org/test/SampleApplication.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2012-2020 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; - -public class SampleApplication { - - public static void main(String[] args) { - System.out.println("I haz been run"); - } - -} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-disable-fork/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-disable-fork/pom.xml deleted file mode 100644 index fa5832c24e..0000000000 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-disable-fork/pom.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - 4.0.0 - org.springframework.boot.maven.it - run-disable-fork - 0.0.1.BUILD-SNAPSHOT - - UTF-8 - @java.version@ - @java.version@ - - - - - @project.groupId@ - @project.artifactId@ - @project.version@ - - false - -Dfoo=bar - ${project.build.sourceDirectory} - - value1 - - - - - - - diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-disable-fork/src/main/java/org/test/SampleApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-disable-fork/src/main/java/org/test/SampleApplication.java deleted file mode 100644 index afabfee12b..0000000000 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-disable-fork/src/main/java/org/test/SampleApplication.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2012-2020 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; - -public class SampleApplication { - - public static void main(String[] args) { - String foo = System.getProperty("foo"); - if ("bar".equals(foo)) { - throw new IllegalStateException("System property foo should not be available. Fork disabled"); - } - System.out.println("I haz been run"); - } - -} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-profiles-fork-disabled/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-profiles-fork-disabled/pom.xml deleted file mode 100644 index 1a222c8897..0000000000 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-profiles-fork-disabled/pom.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - 4.0.0 - org.springframework.boot.maven.it - run-profiles - 0.0.1.BUILD-SNAPSHOT - - UTF-8 - @java.version@ - @java.version@ - - - - - @project.groupId@ - @project.artifactId@ - @project.version@ - - false - - foo - bar - - - - - - diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-profiles-fork-disabled/src/main/java/org/test/SampleApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-profiles-fork-disabled/src/main/java/org/test/SampleApplication.java deleted file mode 100644 index 74cf04b499..0000000000 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-profiles-fork-disabled/src/main/java/org/test/SampleApplication.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2012-2020 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.util.Arrays; - -public class SampleApplication { - - public static void main(String[] args) { - if (args.length < 1) { - throw new IllegalArgumentException("Missing active profile argument " + Arrays.toString(args)); - } - String argument = args[0]; - if (!argument.startsWith("--spring.profiles.active=")) { - throw new IllegalArgumentException("Invalid argument " + argument); - } - int index = args[0].indexOf('='); - String profile = argument.substring(index + 1); - System.out.println("I haz been run with profile(s) '" + profile + "'"); - } - -} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/start-stop-fork-disabled/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/start-stop-fork-disabled/pom.xml deleted file mode 100644 index 8a1a8ad671..0000000000 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/start-stop-fork-disabled/pom.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - 4.0.0 - org.springframework.boot.maven.it - start-stop - 0.0.1.BUILD-SNAPSHOT - - UTF-8 - @java.version@ - @java.version@ - - - - - @project.groupId@ - @project.artifactId@ - @project.version@ - - - pre-integration-test - - start - - - - post-integration-test - - stop - - - - - - - diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/start-stop-fork-disabled/src/main/java/org/test/SampleApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/start-stop-fork-disabled/src/main/java/org/test/SampleApplication.java deleted file mode 100644 index b876d616a0..0000000000 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/start-stop-fork-disabled/src/main/java/org/test/SampleApplication.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2012-2020 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 > 10) { - 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"); - } - - } - -} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java index dc86e049a0..440285282a 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java @@ -18,7 +18,6 @@ package org.springframework.boot.maven; import java.io.File; import java.io.IOException; -import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; @@ -95,7 +94,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { private boolean addResources = false; /** - * Path to agent jars. NOTE: a forked process is required to use this feature. + * Path to agent jars. * @since 2.2.0 */ @Parameter(property = "spring-boot.run.agents") @@ -110,7 +109,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { /** * Current working directory to use for the application. If not specified, basedir - * will be used. NOTE: a forked process is required to use this feature. + * will be used. * @since 1.5.0 */ @Parameter(property = "spring-boot.run.workingDirectory") @@ -119,15 +118,13 @@ 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: a forked process is required to use this feature. * @since 1.1.0 */ @Parameter(property = "spring-boot.run.jvmArguments") private String jvmArguments; /** - * List of JVM system properties to pass to the process. NOTE: a forked process is - * required to use this feature. + * List of JVM system properties to pass to the process. * @since 2.1.0 */ @Parameter @@ -135,8 +132,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { /** * List of Environment variables that should be associated with the forked process - * used to run the application. NOTE: a forked process is required to use this - * feature. + * used to run the application. * @since 2.1.0 */ @Parameter @@ -191,17 +187,6 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { @Parameter(defaultValue = "${project.build.outputDirectory}", required = true) private File classesDirectory; - /** - * Deprecated. 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.0 - * @deprecated since 2.7.0 for removal in 3.0.0 with no replacement - */ - @Parameter(property = "spring-boot.run.fork", defaultValue = "true") - @Deprecated - private boolean fork; - /** * Flag to include the test classpath when running. * @since 1.3.0 @@ -225,71 +210,14 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { run(getStartClass()); } - /** - * Specify if the application process should be forked. - * @return {@code true} if the application process should be forked - * @deprecated since 2.7.0 for removal in 3.0.0 with no replacement - */ - @Deprecated - protected boolean isFork() { - return this.fork; - } - - private boolean hasAgent() { - return (this.agents != null && this.agents.length > 0); - } - - private boolean hasJvmArgs() { - return (this.jvmArguments != null && !this.jvmArguments.isEmpty()) - || (this.systemPropertyVariables != null && !this.systemPropertyVariables.isEmpty()); - } - - private boolean hasWorkingDirectorySet() { - return this.workingDirectory != null; - } - - @SuppressWarnings("deprecation") private void run(String startClassName) throws MojoExecutionException, MojoFailureException { - boolean fork = isFork(); - this.project.getProperties().setProperty("_spring.boot.fork.enabled", Boolean.toString(fork)); - if (fork) { - doRunWithForkedJvm(startClassName); - } - else { - 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. - */ - @Deprecated - protected void logDisabledFork() { - if (getLog().isWarnEnabled()) { - if (hasAgent()) { - getLog().warn("Fork mode disabled, ignoring agent"); - } - if (hasJvmArgs()) { - RunArguments runArguments = resolveJvmArguments(); - getLog().warn("Fork mode disabled, ignoring JVM argument(s) [" - + String.join(" ", runArguments.asArray()) + "]"); - } - if (hasWorkingDirectorySet()) { - getLog().warn("Fork mode disabled, ignoring working directory configuration"); - } - } - } - - private void doRunWithForkedJvm(String startClassName) throws MojoExecutionException, MojoFailureException { List args = new ArrayList<>(); addAgents(args); addJvmArgs(args); addClasspath(args); args.add(startClassName); addArgs(args); - runWithForkedJvm((this.workingDirectory != null) ? this.workingDirectory : this.project.getBasedir(), args, + run((this.workingDirectory != null) ? this.workingDirectory : this.project.getBasedir(), args, determineEnvironmentVariables()); } @@ -301,19 +229,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @throws MojoExecutionException in case of MOJO execution errors * @throws MojoFailureException in case of MOJO failures */ - protected abstract void runWithForkedJvm(File workingDirectory, List args, - Map environmentVariables) throws MojoExecutionException, MojoFailureException; - - /** - * Run with the current VM, using the specified arguments. - * @param startClassName the class to run - * @param arguments the class arguments - * @throws MojoExecutionException in case of MOJO execution errors - * @throws MojoFailureException in case of MOJO failures - * @deprecated since 2.7.0 for removal in 3.0.0 with no replacement - */ - @Deprecated - protected abstract void runWithMavenJvm(String startClassName, String... arguments) + protected abstract void run(File workingDirectory, List args, Map environmentVariables) throws MojoExecutionException, MojoFailureException; /** @@ -510,78 +426,6 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { } - /** - * Isolated {@link ThreadGroup} to capture uncaught exceptions. - */ - class IsolatedThreadGroup extends ThreadGroup { - - private final Object monitor = new Object(); - - private Throwable exception; - - IsolatedThreadGroup(String name) { - super(name); - } - - @Override - public void uncaughtException(Thread thread, Throwable ex) { - if (!(ex instanceof ThreadDeath)) { - synchronized (this.monitor) { - this.exception = (this.exception != null) ? this.exception : ex; - } - getLog().warn(ex); - } - } - - void rethrowUncaughtException() throws MojoExecutionException { - synchronized (this.monitor) { - if (this.exception != null) { - throw new MojoExecutionException( - "An exception occurred while running. " + this.exception.getMessage(), this.exception); - } - } - } - - } - - /** - * Runner used to launch the application. - */ - class LaunchRunner implements Runnable { - - private final String startClassName; - - private final String[] args; - - LaunchRunner(String startClassName, String... args) { - this.startClassName = startClassName; - this.args = (args != null) ? args : new String[] {}; - } - - @Override - public void run() { - Thread thread = Thread.currentThread(); - ClassLoader classLoader = thread.getContextClassLoader(); - try { - Class startClass = Class.forName(this.startClassName, false, classLoader); - Method mainMethod = startClass.getMethod("main", String[].class); - if (!mainMethod.canAccess(null)) { - mainMethod.setAccessible(true); - } - mainMethod.invoke(null, new Object[] { this.args }); - } - catch (NoSuchMethodException ex) { - Exception wrappedEx = new Exception( - "The specified mainClass doesn't contain a main method with appropriate signature.", ex); - thread.getThreadGroup().uncaughtException(thread, wrappedEx); - } - catch (Exception ex) { - thread.getThreadGroup().uncaughtException(thread, ex); - } - } - - } - /** * Format System properties. */ diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java index 33bcba0353..6b911fcc40 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java @@ -18,8 +18,6 @@ package org.springframework.boot.maven; import java.io.File; import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; import java.util.List; import java.util.Map; @@ -48,13 +46,6 @@ 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; - /** * Whether the JVM's launch should be optimized. * @since 2.2.0 @@ -63,19 +54,9 @@ public class RunMojo extends AbstractRunMojo { private boolean optimizedLaunch; @Override - @Deprecated - protected void logDisabledFork() { - super.logDisabledFork(); - if (hasDevtools()) { - getLog().warn("Fork mode disabled, devtools will be disabled"); - } - } - - @Override - @SuppressWarnings("deprecation") protected RunArguments resolveJvmArguments() { RunArguments jvmArguments = super.resolveJvmArguments(); - if (isFork() && this.optimizedLaunch) { + if (this.optimizedLaunch) { jvmArguments.getArgs().addFirst("-XX:TieredStopAtLevel=1"); if (!isJava13OrLater()) { jvmArguments.getArgs().addFirst("-Xverify:none"); @@ -94,7 +75,7 @@ public class RunMojo extends AbstractRunMojo { } @Override - protected void runWithForkedJvm(File workingDirectory, List args, Map environmentVariables) + protected void run(File workingDirectory, List args, Map environmentVariables) throws MojoExecutionException { int exitCode = forkJvm(workingDirectory, args, environmentVariables); if (exitCode == 0 || exitCode == EXIT_CODE_SIGINT) { @@ -115,57 +96,6 @@ public class RunMojo extends AbstractRunMojo { } } - @Override - @Deprecated - protected void runWithMavenJvm(String startClassName, String... arguments) throws MojoExecutionException { - IsolatedThreadGroup threadGroup = new IsolatedThreadGroup(startClassName); - Thread launchThread = new Thread(threadGroup, new LaunchRunner(startClassName, arguments), "main"); - launchThread.setContextClassLoader(new URLClassLoader(getClassPathUrls())); - launchThread.start(); - join(threadGroup); - threadGroup.rethrowUncaughtException(); - } - - private void join(ThreadGroup threadGroup) { - boolean hasNonDaemonThreads; - do { - hasNonDaemonThreads = false; - Thread[] threads = new Thread[threadGroup.activeCount()]; - threadGroup.enumerate(threads); - for (Thread thread : threads) { - if (thread != null && !thread.isDaemon()) { - try { - hasNonDaemonThreads = true; - thread.join(); - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - } - } - while (hasNonDaemonThreads); - } - - private boolean hasDevtools() { - if (this.hasDevtools == null) { - this.hasDevtools = checkForDevtools(); - } - return this.hasDevtools; - } - - private boolean checkForDevtools() { - try { - URL[] urls = getClassPathUrls(); - try (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-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java index b7d60de843..6a5d6b78d8 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java @@ -18,9 +18,7 @@ package org.springframework.boot.maven; import java.io.File; import java.io.IOException; -import java.lang.management.ManagementFactory; import java.net.ConnectException; -import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -65,7 +63,7 @@ public class StartMojo extends AbstractRunMojo { private String jmxName; /** - * The port to use to expose the platform MBeanServer if the application is forked. + * The port to use to expose the platform MBeanServer. */ @Parameter(defaultValue = "9001") private int jmxPort; @@ -88,7 +86,7 @@ public class StartMojo extends AbstractRunMojo { private final Object lock = new Object(); @Override - protected void runWithForkedJvm(File workingDirectory, List args, Map environmentVariables) + protected void run(File workingDirectory, List args, Map environmentVariables) throws MojoExecutionException, MojoFailureException { RunProcess runProcess = runProcess(workingDirectory, args, environmentVariables); try { @@ -113,86 +111,27 @@ public class StartMojo extends AbstractRunMojo { } @Override - @SuppressWarnings("deprecation") protected RunArguments resolveApplicationArguments() { RunArguments applicationArguments = super.resolveApplicationArguments(); applicationArguments.getArgs().addLast(ENABLE_MBEAN_PROPERTY); - if (isFork()) { - applicationArguments.getArgs().addLast(JMX_NAME_PROPERTY_PREFIX + this.jmxName); - } + applicationArguments.getArgs().addLast(JMX_NAME_PROPERTY_PREFIX + this.jmxName); return applicationArguments; } @Override - @SuppressWarnings("deprecation") protected RunArguments resolveJvmArguments() { RunArguments jvmArguments = super.resolveJvmArguments(); - if (isFork()) { - List remoteJmxArguments = new ArrayList<>(); - remoteJmxArguments.add("-Dcom.sun.management.jmxremote"); - remoteJmxArguments.add("-Dcom.sun.management.jmxremote.port=" + this.jmxPort); - remoteJmxArguments.add("-Dcom.sun.management.jmxremote.authenticate=false"); - remoteJmxArguments.add("-Dcom.sun.management.jmxremote.ssl=false"); - remoteJmxArguments.add("-Djava.rmi.server.hostname=127.0.0.1"); - jvmArguments.getArgs().addAll(remoteJmxArguments); - } + List remoteJmxArguments = new ArrayList<>(); + remoteJmxArguments.add("-Dcom.sun.management.jmxremote"); + remoteJmxArguments.add("-Dcom.sun.management.jmxremote.port=" + this.jmxPort); + remoteJmxArguments.add("-Dcom.sun.management.jmxremote.authenticate=false"); + remoteJmxArguments.add("-Dcom.sun.management.jmxremote.ssl=false"); + remoteJmxArguments.add("-Djava.rmi.server.hostname=127.0.0.1"); + jvmArguments.getArgs().addAll(remoteJmxArguments); return jvmArguments; } - @Override - @Deprecated - protected void runWithMavenJvm(String startClassName, String... arguments) throws MojoExecutionException { - IsolatedThreadGroup threadGroup = new IsolatedThreadGroup(startClassName); - Thread launchThread = new Thread(threadGroup, new LaunchRunner(startClassName, arguments), - startClassName + ".main()"); - launchThread.setContextClassLoader(new URLClassLoader(getClassPathUrls())); - launchThread.start(); - waitForSpringApplication(this.wait, this.maxAttempts); - } - - private void waitForSpringApplication(long wait, int maxAttempts) throws MojoExecutionException { - SpringApplicationAdminClient client = new SpringApplicationAdminClient( - ManagementFactory.getPlatformMBeanServer(), this.jmxName); - getLog().debug("Waiting for spring application to start..."); - for (int i = 0; i < maxAttempts; i++) { - if (client.isReady()) { - return; - } - String message = "Spring application is not ready yet, waiting " + wait + "ms (attempt " + (i + 1) + ")"; - getLog().debug(message); - synchronized (this.lock) { - try { - this.lock.wait(wait); - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - throw new IllegalStateException("Interrupted while waiting for Spring Boot app to start."); - } - } - } - throw new MojoExecutionException( - "Spring application did not start before the configured timeout (" + (wait * maxAttempts) + "ms"); - } - - @SuppressWarnings("deprecation") private void waitForSpringApplication() throws MojoFailureException, MojoExecutionException { - try { - if (isFork()) { - waitForForkedSpringApplication(); - } - else { - doWaitForSpringApplication(ManagementFactory.getPlatformMBeanServer()); - } - } - catch (IOException ex) { - throw new MojoFailureException("Could not contact Spring Boot application", ex); - } - catch (Exception ex) { - throw new MojoExecutionException("Could not figure out if the application has started", ex); - } - } - - private void waitForForkedSpringApplication() throws IOException, MojoFailureException, MojoExecutionException { try { getLog().debug("Connecting to local MBeanServer at port " + this.jmxPort); try (JMXConnector connector = execute(this.wait, this.maxAttempts, new CreateJmxConnector(this.jmxPort))) { @@ -206,7 +145,7 @@ public class StartMojo extends AbstractRunMojo { } } catch (IOException ex) { - throw ex; + throw new MojoFailureException("Could not contact Spring Boot application", ex); } catch (Exception ex) { throw new MojoExecutionException("Failed to connect to MBean server at port " + this.jmxPort, ex); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StopMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StopMojo.java index 840691a0fd..7982b0ad8e 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StopMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StopMojo.java @@ -17,7 +17,6 @@ package org.springframework.boot.maven; import java.io.IOException; -import java.lang.management.ManagementFactory; import javax.management.InstanceNotFoundException; import javax.management.MBeanServerConnection; @@ -48,18 +47,6 @@ public class StopMojo extends AbstractMojo { @Parameter(defaultValue = "${project}", readonly = true, required = true) private MavenProject project; - /** - * Flag to indicate if the process to stop was forked. By default, the value is - * inherited from the {@link MavenProject} with a fallback on the default fork value - * ({@code true}). If it is set, it must match the value used to {@link StartMojo - * start} the process. - * @since 1.3.0 - * @deprecated since 2.7.0 for removal in 3.0.0 with no replacement - */ - @Parameter(property = "spring-boot.stop.fork") - @Deprecated - private Boolean fork; - /** * The JMX name of the automatically deployed MBean managing the lifecycle of the * application. @@ -68,8 +55,7 @@ public class StopMojo extends AbstractMojo { private String jmxName; /** - * The port to use to lookup the platform MBeanServer if the application has been - * forked. + * The port to use to lookup the platform MBeanServer. */ @Parameter(defaultValue = "9001") private int jmxPort; @@ -82,20 +68,15 @@ public class StopMojo extends AbstractMojo { private boolean skip; @Override - @SuppressWarnings("deprecation") public void execute() throws MojoExecutionException, MojoFailureException { if (this.skip) { getLog().debug("skipping stop as per configuration."); return; } getLog().info("Stopping application..."); - try { - if (isForked()) { - stopForkedProcess(); - } - else { - stop(); - } + try (JMXConnector connector = SpringApplicationAdminClient.connect(this.jmxPort)) { + MBeanServerConnection connection = connector.getMBeanServerConnection(); + stop(connection); } catch (IOException ex) { // The response won't be received as the server has died - ignoring @@ -103,36 +84,13 @@ public class StopMojo extends AbstractMojo { } } - @Deprecated - private boolean isForked() { - if (this.fork != null) { - return this.fork; - } - String forkFromStart = this.project.getProperties().getProperty("_spring.boot.fork.enabled"); - if (forkFromStart != null) { - return Boolean.parseBoolean(forkFromStart); - } - return true; - } - - private void stopForkedProcess() throws IOException, MojoFailureException, MojoExecutionException { - try (JMXConnector connector = SpringApplicationAdminClient.connect(this.jmxPort)) { - MBeanServerConnection connection = connector.getMBeanServerConnection(); - doStop(connection); - } - } - - private void stop() throws IOException, MojoFailureException, MojoExecutionException { - doStop(ManagementFactory.getPlatformMBeanServer()); - } - - private void doStop(MBeanServerConnection connection) throws IOException, MojoExecutionException { + private void stop(MBeanServerConnection connection) throws IOException, MojoExecutionException { try { new SpringApplicationAdminClient(connection, this.jmxName).stop(); } catch (InstanceNotFoundException ex) { - throw new MojoExecutionException("Spring application lifecycle JMX bean not found (fork is " + this.fork - + "). Could not stop application gracefully", ex); + throw new MojoExecutionException( + "Spring application lifecycle JMX bean not found. Could not stop application gracefully", ex); } }