diff --git a/spring-boot-cli/src/it/java/org/springframework/boot/cli/JarCommandIT.java b/spring-boot-cli/src/it/java/org/springframework/boot/cli/JarCommandIT.java index 5d14faf0fb..82e766e9e6 100644 --- a/spring-boot-cli/src/it/java/org/springframework/boot/cli/JarCommandIT.java +++ b/spring-boot-cli/src/it/java/org/springframework/boot/cli/JarCommandIT.java @@ -22,7 +22,7 @@ import org.junit.Test; import org.springframework.boot.cli.command.jar.JarCommand; import org.springframework.boot.cli.infrastructure.CommandLineInvoker; import org.springframework.boot.cli.infrastructure.CommandLineInvoker.Invocation; -import org.springframework.boot.cli.util.JavaExecutable; +import org.springframework.boot.loader.tools.JavaExecutable; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/shell/ForkProcessCommand.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/shell/ForkProcessCommand.java index 6d655d058e..f05dac3990 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/shell/ForkProcessCommand.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/shell/ForkProcessCommand.java @@ -23,7 +23,7 @@ import java.util.List; import org.springframework.boot.cli.command.Command; import org.springframework.boot.cli.command.options.OptionHelp; -import org.springframework.boot.cli.util.JavaExecutable; +import org.springframework.boot.loader.tools.JavaExecutable; /** * Decorate an existing command to run it by forking the current java process. diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/shell/RunProcessCommand.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/shell/RunProcessCommand.java index 613d4a37ae..d040e99875 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/shell/RunProcessCommand.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/shell/RunProcessCommand.java @@ -16,16 +16,13 @@ package org.springframework.boot.cli.command.shell; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; -import java.lang.reflect.Method; import java.util.Arrays; import java.util.Collection; import org.springframework.boot.cli.command.AbstractCommand; import org.springframework.boot.cli.command.Command; -import org.springframework.util.ReflectionUtils; +import org.springframework.boot.loader.tools.RunProcess; /** * Special {@link Command} used to run a process from the shell. NOTE: this command is not @@ -35,16 +32,8 @@ import org.springframework.util.ReflectionUtils; */ class RunProcessCommand extends AbstractCommand { - private static final Method INHERIT_IO_METHOD = ReflectionUtils.findMethod( - ProcessBuilder.class, "inheritIO"); - - private static final long JUST_ENDED_LIMIT = 500; - private final String[] command; - - private volatile Process process; - - private volatile long endTime; + private volatile RunProcess process; public RunProcessCommand(String... command) { super(null, null); @@ -57,94 +46,12 @@ class RunProcessCommand extends AbstractCommand { } protected void run(Collection args) throws IOException { - ProcessBuilder builder = new ProcessBuilder(this.command); - builder.command().addAll(args); - builder.redirectErrorStream(true); - boolean inheritedIO = inheritIO(builder); - try { - this.process = builder.start(); - if (!inheritedIO) { - redirectOutput(this.process); - } - try { - this.process.waitFor(); - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - finally { - this.endTime = System.currentTimeMillis(); - this.process = null; - } - } - - private boolean inheritIO(ProcessBuilder builder) { - try { - INHERIT_IO_METHOD.invoke(builder); - return true; - } - catch (Exception ex) { - return false; - } - } - - private void redirectOutput(Process process) { - final BufferedReader reader = new BufferedReader(new InputStreamReader( - process.getInputStream())); - new Thread() { - @Override - public void run() { - try { - String line = reader.readLine(); - while (line != null) { - System.out.println(line); - line = reader.readLine(); - } - reader.close(); - } - catch (Exception ex) { - } - }; - }.start(); + this.process = new RunProcess(this.command); + this.process.run(args.toArray(new String[args.size()])); } - /** - * @return the running process or {@code null} - */ - public Process getRunningProcess() { - return this.process; - } - - /** - * @return {@code true} if the process was stopped. - */ public boolean handleSigInt() { - - // if the process has just ended, probably due to this SIGINT, consider handled. - if (hasJustEnded()) { - return true; - } - - // destroy the running process - Process process = this.process; - if (process != null) { - try { - process.destroy(); - process.waitFor(); - this.process = null; - return true; - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - - return false; - } - - public boolean hasJustEnded() { - return System.currentTimeMillis() < (this.endTime + JUST_ENDED_LIMIT); + return this.process.handleSigInt(); } } diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/util/JavaExecutable.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/util/JavaExecutable.java deleted file mode 100644 index d03d8e4725..0000000000 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/util/JavaExecutable.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.springframework.boot.cli.util; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * Provides access to the java binary executable, regardless of OS. - * - * @author Phillip Webb - */ -public class JavaExecutable { - - private File file; - - public JavaExecutable() { - String javaHome = System.getProperty("java.home"); - Assert.state(StringUtils.hasLength(javaHome), - "Unable to find java executable due to missing 'java.home'"); - this.file = findInJavaHome(javaHome); - } - - private File findInJavaHome(String javaHome) { - File bin = new File(new File(javaHome), "bin"); - File command = new File(bin, "java.exe"); - command = (command.exists() ? command : new File(bin, "java")); - Assert.state(command.exists(), "Unable to find java in " + javaHome); - return command; - } - - public ProcessBuilder processBuilder(String... arguments) { - ProcessBuilder processBuilder = new ProcessBuilder(toString()); - processBuilder.command().addAll(Arrays.asList(arguments)); - return processBuilder; - } - - @Override - public String toString() { - try { - return this.file.getCanonicalPath(); - } - catch (IOException ex) { - throw new IllegalStateException(ex); - } - } - -} 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 da16c80c00..e8873abf65 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 @@ -48,7 +48,7 @@ public class RunProcess { this.command = command; } - public void run(String... args) throws Exception { + public void run(String... args) throws IOException { run(Arrays.asList(args)); }