From 3cccc732df15320289c65ff05523d9f8a9f98e49 Mon Sep 17 00:00:00 2001 From: Plamen Totev Date: Sat, 13 Aug 2016 21:45:00 +0300 Subject: [PATCH 1/2] Add workingDirectory option for Maven plugin run/start Add configuration option that specifies the working directory to use to run/start the application via the Maven plugin. Closes gh-6243 --- .../boot/loader/tools/RunProcess.java | 22 ++++++++++++- .../src/it/run-disable-fork/pom.xml | 1 + .../src/it/run-disable-fork/verify.groovy | 1 + .../src/it/run-working-directory/pom.xml | 31 +++++++++++++++++++ .../main/java/org/test/SampleApplication.java | 26 ++++++++++++++++ .../it/run-working-directory/verify.groovy | 6 ++++ .../boot/maven/AbstractRunMojo.java | 26 +++++++++++++--- .../springframework/boot/maven/RunMojo.java | 5 +-- .../springframework/boot/maven/StartMojo.java | 9 +++--- 9 files changed, 115 insertions(+), 12 deletions(-) create mode 100644 spring-boot-tools/spring-boot-maven-plugin/src/it/run-working-directory/pom.xml create mode 100644 spring-boot-tools/spring-boot-maven-plugin/src/it/run-working-directory/src/main/java/org/test/SampleApplication.java create mode 100644 spring-boot-tools/spring-boot-maven-plugin/src/it/run-working-directory/verify.groovy diff --git a/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/RunProcess.java b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/RunProcess.java index 4cef7b9d36c..36b0a217be0 100644 --- a/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/RunProcess.java +++ b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/RunProcess.java @@ -17,6 +17,7 @@ package org.springframework.boot.loader.tools; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.lang.reflect.Method; @@ -41,16 +42,34 @@ public class RunProcess { private static final long JUST_ENDED_LIMIT = 500; + private File workingDirectory; + private final String[] command; private volatile Process process; private volatile long endTime; - public RunProcess(String... command) { + /** + * Creates new {@link RunProcess} instance for the specified command + * and working directory. + * @param workingDirectory the working directory of the child process or {@code null} + * to run in the working directory of the current Java process + * @param command the program to execute and it's arguments + */ + public RunProcess(File workingDirectory, String... command) { + this.workingDirectory = workingDirectory; this.command = command; } + /** + * Creates new {@link RunProcess} instance for the specified command. + * @param command the program to execute and it's arguments + */ + public RunProcess(String... command) { + this(null, command); + } + public int run(boolean waitForProcess, String... args) throws IOException { return run(waitForProcess, Arrays.asList(args)); } @@ -58,6 +77,7 @@ public class RunProcess { protected int run(boolean waitForProcess, Collection args) throws IOException { ProcessBuilder builder = new ProcessBuilder(this.command); + builder.directory(workingDirectory); builder.command().addAll(args); builder.redirectErrorStream(true); boolean inheritedIO = inheritIO(builder); diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/pom.xml b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/pom.xml index 1cafbfc7890..9f537fe47ff 100644 --- a/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/pom.xml +++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/pom.xml @@ -23,6 +23,7 @@ false -Dfoo=bar + ${project.build.sourceDirectory} diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/verify.groovy b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/verify.groovy index cb445e7a2c9..baaf7a9a59b 100644 --- a/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/verify.groovy +++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/verify.groovy @@ -3,4 +3,5 @@ import static org.junit.Assert.assertTrue def file = new File(basedir, "build.log") assertTrue file.text.contains("I haz been run") assertTrue file.text.contains("Fork mode disabled, ignoring JVM argument(s) [-Dfoo=bar]") +assertTrue file.text.contains("Fork mode disabled, ignoring working directory configuration") diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/run-working-directory/pom.xml b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-working-directory/pom.xml new file mode 100644 index 00000000000..9cfd04f3b1f --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-working-directory/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + org.springframework.boot.maven.it + run-working-directory + 0.0.1.BUILD-SNAPSHOT + + UTF-8 + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + package + + run + + + ${project.build.sourceDirectory} + + + + + + + diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/run-working-directory/src/main/java/org/test/SampleApplication.java b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-working-directory/src/main/java/org/test/SampleApplication.java new file mode 100644 index 00000000000..6fff81aaa2f --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-working-directory/src/main/java/org/test/SampleApplication.java @@ -0,0 +1,26 @@ +/* + * 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.test; + +public class SampleApplication { + + public static void main(String[] args) { + String workingDirectory = System.getProperty("user.dir"); + System.out.println(String.format("I haz been run from %s", workingDirectory)); + } + +} diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/run-working-directory/verify.groovy b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-working-directory/verify.groovy new file mode 100644 index 00000000000..4f1b8234fc5 --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-working-directory/verify.groovy @@ -0,0 +1,6 @@ +import static org.junit.Assert.assertTrue + +def file = new File(basedir, "build.log") +def workDir = new File(basedir, "src/main/java").getAbsolutePath() +assertTrue file.text.contains("I haz been run from ${workDir}") + 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 086664afe3f..969f8eade67 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 @@ -87,6 +87,14 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { @Parameter(property = "run.noverify") private Boolean noverify; + /** + * The working directory of the application. If specified by default the process + * will be started by forking a new JVM. + * @since 1.5 + */ + @Parameter(property = "run.workingDirectory") + private File workingDirectory; + /** * 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. @@ -140,8 +148,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, or if devtools is - * present. + * automatically enabled if an agent, jvmArguments or working directory are + * specified, or if devtools is present. * @since 1.2 */ @Parameter(property = "fork") @@ -185,7 +193,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @see #logDisabledFork() */ protected boolean enableForkByDefault() { - return hasAgent() || hasJvmArgs(); + return hasAgent() || hasJvmArgs() || hasWorkingDirectorySet(); } private boolean hasAgent() { @@ -196,6 +204,10 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { return (this.jvmArguments != null && this.jvmArguments.length() > 0); } + private boolean hasWorkingDirectorySet() { + return (this.workingDirectory != null); + } + private void findAgent() { try { if (this.agent == null || this.agent.length == 0) { @@ -248,6 +260,9 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { getLog().warn("Fork mode disabled, ignoring JVM argument(s) [" + this.jvmArguments + "]"); } + if (hasWorkingDirectorySet()) { + getLog().warn("Fork mode disabled, ignoring working directory configuration"); + } } private void doRunWithForkedJvm(String startClassName) @@ -258,16 +273,17 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { addClasspath(args); args.add(startClassName); addArgs(args); - runWithForkedJvm(args); + runWithForkedJvm(this.workingDirectory, args); } /** * Run with a forked VM, using the specified command line arguments. + * @param workingDirectory the working directory of the forked JVM * @param args the arguments (JVM arguments and application arguments) * @throws MojoExecutionException in case of MOJO execution errors * @throws MojoFailureException in case of MOJO failures */ - protected abstract void runWithForkedJvm(List args) + protected abstract void runWithForkedJvm(File workingDirectory, List args) throws MojoExecutionException, MojoFailureException; /** 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 7750556c3dc..58590c55fe3 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 @@ -17,6 +17,7 @@ package org.springframework.boot.maven; import java.net.URL; +import java.io.File; import java.net.URLClassLoader; import java.util.List; @@ -63,9 +64,9 @@ public class RunMojo extends AbstractRunMojo { } @Override - protected void runWithForkedJvm(List args) throws MojoExecutionException { + protected void runWithForkedJvm(File workingDirectory, List args) throws MojoExecutionException { try { - RunProcess runProcess = new RunProcess(new JavaExecutable().toString()); + RunProcess runProcess = new RunProcess(workingDirectory, new JavaExecutable().toString()); Runtime.getRuntime() .addShutdownHook(new Thread(new RunProcessKiller(runProcess))); int exitCode = runProcess.run(true, args.toArray(new String[args.size()])); diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java index 74fe47655c4..8895311130d 100644 --- a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java +++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java @@ -16,6 +16,7 @@ package org.springframework.boot.maven; +import java.io.File; import java.io.IOException; import java.lang.management.ManagementFactory; import java.net.ConnectException; @@ -87,9 +88,9 @@ public class StartMojo extends AbstractRunMojo { private final Object lock = new Object(); @Override - protected void runWithForkedJvm(List args) + protected void runWithForkedJvm(File workingDirectory, List args) throws MojoExecutionException, MojoFailureException { - RunProcess runProcess = runProcess(args); + RunProcess runProcess = runProcess(args, workingDirectory); try { waitForSpringApplication(); } @@ -103,9 +104,9 @@ public class StartMojo extends AbstractRunMojo { } } - private RunProcess runProcess(List args) throws MojoExecutionException { + private RunProcess runProcess(List args, File workingDirectory) throws MojoExecutionException { try { - RunProcess runProcess = new RunProcess(new JavaExecutable().toString()); + RunProcess runProcess = new RunProcess(workingDirectory, new JavaExecutable().toString()); runProcess.run(false, args.toArray(new String[args.size()])); return runProcess; } From 28ed59ca6e3a7ac7f8eb8138d6d7758b66185625 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 11 Oct 2016 15:32:48 +0200 Subject: [PATCH 2/2] Polish contribution Closes gh-6645 --- .../springframework/boot/loader/tools/RunProcess.java | 2 +- .../springframework/boot/maven/AbstractRunMojo.java | 5 +++-- .../java/org/springframework/boot/maven/RunMojo.java | 2 +- .../java/org/springframework/boot/maven/StartMojo.java | 10 ++++++---- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/RunProcess.java b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/RunProcess.java index 36b0a217be0..ebf81c91415 100644 --- a/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/RunProcess.java +++ b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/RunProcess.java @@ -77,7 +77,7 @@ public class RunProcess { protected int run(boolean waitForProcess, Collection args) throws IOException { ProcessBuilder builder = new ProcessBuilder(this.command); - builder.directory(workingDirectory); + builder.directory(this.workingDirectory); builder.command().addAll(args); builder.redirectErrorStream(true); boolean inheritedIO = inheritIO(builder); 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 969f8eade67..0cf076b5899 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 @@ -88,8 +88,9 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { private Boolean noverify; /** - * The working directory of the application. If specified by default the process - * will be started by forking a new JVM. + * 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. * @since 1.5 */ @Parameter(property = "run.workingDirectory") 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 58590c55fe3..55843def717 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,8 +16,8 @@ package org.springframework.boot.maven; -import java.net.URL; import java.io.File; +import java.net.URL; import java.net.URLClassLoader; import java.util.List; diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java index 8895311130d..595ef0e1243 100644 --- a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java +++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * 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. @@ -90,7 +90,7 @@ public class StartMojo extends AbstractRunMojo { @Override protected void runWithForkedJvm(File workingDirectory, List args) throws MojoExecutionException, MojoFailureException { - RunProcess runProcess = runProcess(args, workingDirectory); + RunProcess runProcess = runProcess(workingDirectory, args); try { waitForSpringApplication(); } @@ -104,9 +104,11 @@ public class StartMojo extends AbstractRunMojo { } } - private RunProcess runProcess(List args, File workingDirectory) throws MojoExecutionException { + private RunProcess runProcess(File workingDirectory, List args) + throws MojoExecutionException { try { - RunProcess runProcess = new RunProcess(workingDirectory, new JavaExecutable().toString()); + RunProcess runProcess = new RunProcess(workingDirectory, + new JavaExecutable().toString()); runProcess.run(false, args.toArray(new String[args.size()])); return runProcess; }