Review, refactor and polish all Process classes in the org.springframework.data.gemfire.tests.process package.
This commit is contained in:
@@ -17,29 +17,28 @@
|
||||
package org.springframework.data.gemfire.tests.process;
|
||||
|
||||
/**
|
||||
* The PidUnavailableException class is a RuntimeException indicating that the process ID (PID) is unobtainable for
|
||||
* the current process.
|
||||
* The {@link PidNotFoundException} class is a {@link RuntimeException} indicating that the process ID (PID)
|
||||
* is unobtainable for the current {@link Process}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see RuntimeException
|
||||
* @since 1.5.0
|
||||
* @see java.lang.RuntimeException
|
||||
* @since 0.0.1
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class PidUnavailableException extends RuntimeException {
|
||||
public class PidNotFoundException extends RuntimeException {
|
||||
|
||||
public PidUnavailableException() {
|
||||
public PidNotFoundException() {
|
||||
}
|
||||
|
||||
public PidUnavailableException(final String message) {
|
||||
public PidNotFoundException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public PidUnavailableException(final Throwable cause) {
|
||||
public PidNotFoundException(final Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public PidUnavailableException(final String message, final Throwable cause) {
|
||||
public PidNotFoundException(final String message, final Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,9 +32,10 @@ import org.springframework.util.StringUtils;
|
||||
* for a running process.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see ProcessBuilder
|
||||
* @see org.springframework.data.gemfire.process.ProcessExecutor
|
||||
* @since 1.5.0
|
||||
* @see java.lang.Process
|
||||
* @see java.lang.ProcessBuilder
|
||||
* @see org.springframework.data.gemfire.tests.process.ProcessExecutor
|
||||
* @since 0.0.1
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class ProcessConfiguration {
|
||||
@@ -48,7 +49,9 @@ public class ProcessConfiguration {
|
||||
private final Map<String, String> environment;
|
||||
|
||||
public static ProcessConfiguration create(ProcessBuilder processBuilder) {
|
||||
Assert.notNull(processBuilder, "The ProcessBuilder used to configure and start the Process must not be null");
|
||||
|
||||
Assert.notNull(processBuilder,
|
||||
"The ProcessBuilder used to configure and start the Process must not be null");
|
||||
|
||||
return new ProcessConfiguration(processBuilder.command(), processBuilder.directory(),
|
||||
processBuilder.environment(), processBuilder.redirectErrorStream());
|
||||
@@ -57,22 +60,22 @@ public class ProcessConfiguration {
|
||||
public ProcessConfiguration(List<String> command, File workingDirectory, Map<String, String> environment,
|
||||
boolean redirectErrorStream) {
|
||||
|
||||
Assert.notEmpty(command, "Process command must be specified");
|
||||
Assert.notEmpty(command, "Process command is required");
|
||||
|
||||
Assert.isTrue(FileSystemUtils.isDirectory(workingDirectory), String.format(
|
||||
"Process working directory [%s] is not valid", workingDirectory));
|
||||
Assert.isTrue(FileSystemUtils.isDirectory(workingDirectory),
|
||||
String.format("Process working directory [%s] is not valid", workingDirectory));
|
||||
|
||||
this.command = new ArrayList<String>(command);
|
||||
this.command = Collections.unmodifiableList(new ArrayList<>(command));
|
||||
this.workingDirectory = workingDirectory;
|
||||
this.redirectingErrorStream = redirectErrorStream;
|
||||
|
||||
this.environment = (environment != null
|
||||
? Collections.unmodifiableMap(new HashMap<String, String>(environment))
|
||||
: Collections.<String, String>emptyMap());
|
||||
this.environment = environment != null
|
||||
? Collections.unmodifiableMap(new HashMap<>(environment))
|
||||
: Collections.emptyMap();
|
||||
}
|
||||
|
||||
public List<String> getCommand() {
|
||||
return Collections.unmodifiableList(command);
|
||||
return this.command;
|
||||
}
|
||||
|
||||
public String getCommandString() {
|
||||
@@ -80,19 +83,20 @@ public class ProcessConfiguration {
|
||||
}
|
||||
|
||||
public Map<String, String> getEnvironment() {
|
||||
return environment;
|
||||
return this.environment;
|
||||
}
|
||||
|
||||
public boolean isRedirectingErrorStream() {
|
||||
return redirectingErrorStream;
|
||||
return this.redirectingErrorStream;
|
||||
}
|
||||
|
||||
public File getWorkingDirectory() {
|
||||
return workingDirectory;
|
||||
return this.workingDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
return "{ command = ".concat(getCommandString())
|
||||
.concat(", workingDirectory = ".concat(getWorkingDirectory().getAbsolutePath()))
|
||||
.concat(", environment = ".concat(String.valueOf(getEnvironment())))
|
||||
|
||||
@@ -39,7 +39,7 @@ import org.springframework.util.StringUtils;
|
||||
* @see java.lang.System
|
||||
* @see org.springframework.data.gemfire.tests.process.ProcessConfiguration
|
||||
* @see org.springframework.data.gemfire.tests.process.ProcessWrapper
|
||||
* @since 1.5.0
|
||||
* @since 0.0.1
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class ProcessExecutor {
|
||||
@@ -48,8 +48,8 @@ public abstract class ProcessExecutor {
|
||||
|
||||
public static final String JAVA_CLASSPATH = System.getProperty("java.class.path");
|
||||
|
||||
protected static final String SPRING_GEMFIRE_SYSTEM_PROPERTY_PREFIX = "spring.gemfire.";
|
||||
protected static final String SPRING_DATA_GEMFIRE_SYSTEM_PROPERTY_PREFIX = "spring.data.gemfire.";
|
||||
protected static final String SPRING_GEMFIRE_SYSTEM_PROPERTY_PREFIX = "spring.gemfire.";
|
||||
|
||||
public static ProcessWrapper launch(Class<?> type, String... args) throws IOException {
|
||||
return launch(FileSystemUtils.WORKING_DIRECTORY, type, args);
|
||||
@@ -77,6 +77,7 @@ public abstract class ProcessExecutor {
|
||||
}
|
||||
|
||||
protected static String[] buildCommand(String classpath, Class<?> type, String... args) {
|
||||
|
||||
Assert.notNull(type, "The main Java class to launch must not be null");
|
||||
|
||||
List<String> command = new ArrayList<>();
|
||||
@@ -93,7 +94,7 @@ public abstract class ProcessExecutor {
|
||||
if (isJvmOption(arg)) {
|
||||
command.add(arg);
|
||||
}
|
||||
else if (!StringUtils.isEmpty(arg)) {
|
||||
else if (isValidArgument(arg)) {
|
||||
programArguments.add(arg);
|
||||
}
|
||||
}
|
||||
@@ -105,6 +106,7 @@ public abstract class ProcessExecutor {
|
||||
}
|
||||
|
||||
protected static Collection<? extends String> getSpringGemFireSystemProperties() {
|
||||
|
||||
return System.getProperties().stringPropertyNames().stream()
|
||||
.filter(property -> property.startsWith(SPRING_DATA_GEMFIRE_SYSTEM_PROPERTY_PREFIX)
|
||||
|| property.startsWith(SPRING_GEMFIRE_SYSTEM_PROPERTY_PREFIX))
|
||||
@@ -116,7 +118,12 @@ public abstract class ProcessExecutor {
|
||||
return (StringUtils.hasText(option) && (option.startsWith("-D") || option.startsWith("-X")));
|
||||
}
|
||||
|
||||
protected static boolean isValidArgument(String argument) {
|
||||
return StringUtils.hasText(argument);
|
||||
}
|
||||
|
||||
protected static File validateDirectory(File workingDirectory) {
|
||||
|
||||
Assert.isTrue(workingDirectory != null && (workingDirectory.isDirectory() || workingDirectory.mkdirs()),
|
||||
String.format("Failed to create working directory [%s]", workingDirectory));
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ import java.util.EventListener;
|
||||
* {@link Process process's} standard output steam or standard error stream.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see EventListener
|
||||
* @since 1.5.0
|
||||
* @see java.util.EventListener
|
||||
* @since 0.0.1
|
||||
*/
|
||||
public interface ProcessInputStreamListener extends EventListener {
|
||||
|
||||
@@ -33,8 +33,8 @@ public interface ProcessInputStreamListener extends EventListener {
|
||||
* or standard error streams.
|
||||
*
|
||||
* @param input {@link String} containing output from the {@link Process} that this listener is listening to.
|
||||
* @see Process#getErrorStream()
|
||||
* @see Process#getInputStream()
|
||||
* @see java.lang.Process#getErrorStream()
|
||||
* @see java.lang.Process#getInputStream()
|
||||
*/
|
||||
void onInput(String input);
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author John Blum
|
||||
* @see File
|
||||
* @see Process
|
||||
* @since 1.5.0
|
||||
* @since 0.0.1
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class ProcessUtils {
|
||||
@@ -53,12 +53,15 @@ public abstract class ProcessUtils {
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static int currentPid() {
|
||||
|
||||
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
|
||||
|
||||
String runtimeMXBeanName = runtimeMXBean.getName();
|
||||
|
||||
Exception cause = null;
|
||||
|
||||
if (StringUtils.hasText(runtimeMXBeanName)) {
|
||||
|
||||
int atSignIndex = runtimeMXBeanName.indexOf('@');
|
||||
|
||||
if (atSignIndex > 0) {
|
||||
@@ -71,32 +74,20 @@ public abstract class ProcessUtils {
|
||||
}
|
||||
}
|
||||
|
||||
throw new PidUnavailableException(String.format("Process ID (PID) not available [%s]", runtimeMXBeanName),
|
||||
cause);
|
||||
throw new PidNotFoundException(String.format("Process ID (PID) not available [%s]",
|
||||
runtimeMXBeanName), cause);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static boolean isAlive(Process process) {
|
||||
return (process != null && process.isAlive());
|
||||
return process != null && process.isAlive();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static boolean isRunning(int processId) {
|
||||
/*
|
||||
for (VirtualMachineDescriptor vmDescriptor : VirtualMachine.list()) {
|
||||
if (String.valueOf(processId).equals(vmDescriptor.id())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
*/
|
||||
|
||||
throw new UnsupportedOperationException("operation not supported");
|
||||
throw new UnsupportedOperationException("Operation not supported");
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static boolean isRunning(Process process) {
|
||||
|
||||
try {
|
||||
process.exitValue();
|
||||
return false;
|
||||
@@ -106,40 +97,24 @@ public abstract class ProcessUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static void signalStop(Process process) throws IOException {
|
||||
if (isRunning(process)) {
|
||||
OutputStream processOutputStream = process.getOutputStream();
|
||||
processOutputStream.write(TERM_TOKEN.concat("\n").getBytes());
|
||||
processOutputStream.flush();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("all")
|
||||
public static void waitForStopSignal() {
|
||||
Scanner in = new Scanner(System.in);
|
||||
while (!TERM_TOKEN.equals(in.next()));
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static int findAndReadPid(File workingDirectory) {
|
||||
|
||||
File pidFile = findPidFile(workingDirectory);
|
||||
|
||||
if (pidFile == null) {
|
||||
throw new PidUnavailableException(String.format(
|
||||
"No PID file was found in working directory [%s] or any of it's sub-directories",
|
||||
throw new PidNotFoundException(
|
||||
String.format("No PID file was found in working directory [%s] or any of it's sub-directories",
|
||||
workingDirectory));
|
||||
}
|
||||
|
||||
return readPid(pidFile);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("all")
|
||||
protected static File findPidFile(File workingDirectory) {
|
||||
Assert.isTrue(FileSystemUtils.isDirectory(workingDirectory), String.format(
|
||||
"File [%s] is not a valid directory", workingDirectory));
|
||||
|
||||
Assert.isTrue(FileSystemUtils.isDirectory(workingDirectory),
|
||||
String.format("File [%s] is not a valid directory", workingDirectory));
|
||||
|
||||
for (File file : workingDirectory.listFiles(DirectoryPidFileFilter.INSTANCE)) {
|
||||
if (file.isDirectory()) {
|
||||
@@ -154,45 +129,48 @@ public abstract class ProcessUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("all")
|
||||
public static int readPid(File pidFile) {
|
||||
Assert.isTrue(pidFile != null && pidFile.isFile(), String.format(
|
||||
"File [%s] is not a valid file", pidFile));
|
||||
|
||||
Assert.isTrue(pidFile != null && pidFile.isFile(),
|
||||
String.format("File [%s] is not a valid file", pidFile));
|
||||
|
||||
BufferedReader fileReader = null;
|
||||
|
||||
String pidValue = null;
|
||||
|
||||
try {
|
||||
|
||||
fileReader = new BufferedReader(new FileReader(pidFile));
|
||||
pidValue = String.valueOf(fileReader.readLine()).trim();
|
||||
|
||||
return Integer.parseInt(pidValue);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
throw new PidUnavailableException(String.format("PID file [%s] not found", pidFile), e);
|
||||
catch (FileNotFoundException cause) {
|
||||
throw new PidNotFoundException(String.format("PID file [%s] not found", pidFile), cause);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new PidUnavailableException(String.format("failed to read PID from file [%s]", pidFile), e);
|
||||
catch (IOException cause) {
|
||||
throw new PidNotFoundException(String.format("Failed to read PID from file [%s]", pidFile), cause);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new PidUnavailableException(String.format(
|
||||
"value [%1$s] from PID file [%2$s] was not a valid numerical PID", pidValue, pidFile), e);
|
||||
catch (NumberFormatException cause) {
|
||||
throw new PidNotFoundException(String.format("Value [%1$s] from PID file [%2$s] was not a valid numerical PID",
|
||||
pidValue, pidFile), cause);
|
||||
}
|
||||
finally {
|
||||
IOUtils.close(fileReader);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("all")
|
||||
public static void writePid(File pidFile, int pid) throws IOException {
|
||||
Assert.isTrue(pidFile != null && (pidFile.isFile() || pidFile.createNewFile()), String.format(
|
||||
"File [%s] is not a valid file", pidFile));
|
||||
|
||||
Assert.isTrue(pidFile != null && (pidFile.isFile() || pidFile.createNewFile()),
|
||||
String.format("File [%s] is not a valid file", pidFile));
|
||||
|
||||
Assert.isTrue(pid > 0, String.format("PID [%d] must greater than 0", pid));
|
||||
|
||||
PrintWriter fileWriter = new PrintWriter(new BufferedWriter(new FileWriter(pidFile, false), 16), true);
|
||||
PrintWriter fileWriter = new PrintWriter(new BufferedWriter(
|
||||
new FileWriter(pidFile, false), 16), true);
|
||||
|
||||
try {
|
||||
fileWriter.println(pid);
|
||||
@@ -203,28 +181,37 @@ public abstract class ProcessUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static void signalStop(Process process) throws IOException {
|
||||
|
||||
if (isRunning(process)) {
|
||||
OutputStream processOutputStream = process.getOutputStream();
|
||||
processOutputStream.write(TERM_TOKEN.concat("\n").getBytes());
|
||||
processOutputStream.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static void waitForStopSignal() {
|
||||
|
||||
Scanner in = new Scanner(System.in);
|
||||
|
||||
while (!TERM_TOKEN.equals(in.next()));
|
||||
}
|
||||
|
||||
protected static class DirectoryPidFileFilter extends PidFileFilter {
|
||||
|
||||
protected static final DirectoryPidFileFilter INSTANCE = new DirectoryPidFileFilter();
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public boolean accept(File path) {
|
||||
return (path != null && (path.isDirectory() || super.accept(path)));
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected static class PidFileFilter implements FileFilter {
|
||||
|
||||
protected static final PidFileFilter INSTANCE = new PidFileFilter();
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public boolean accept(File path) {
|
||||
return (path != null && path.isFile() && path.getName().toLowerCase().endsWith(".pid"));
|
||||
|
||||
@@ -49,7 +49,7 @@ import org.springframework.util.Assert;
|
||||
* @author John Blum
|
||||
* @see Process
|
||||
* @see ProcessBuilder
|
||||
* @since 1.5.0
|
||||
* @since 0.0.1
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class ProcessWrapper {
|
||||
@@ -63,15 +63,16 @@ public class ProcessWrapper {
|
||||
protected final Logger log = Logger.getLogger(getClass().getName());
|
||||
|
||||
private final Process process;
|
||||
|
||||
private final ProcessConfiguration processConfiguration;
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public ProcessWrapper(Process process, ProcessConfiguration processConfiguration) {
|
||||
Assert.notNull(process, "Process must not be null");
|
||||
|
||||
Assert.notNull(process, "Process is required");
|
||||
|
||||
Assert.notNull(processConfiguration, "The context and configuration meta-data providing details"
|
||||
+ " about the environment in which the process is running and how the process was configured and executed"
|
||||
+ " must not be null");
|
||||
+ " is required");
|
||||
|
||||
this.process = process;
|
||||
this.processConfiguration = processConfiguration;
|
||||
@@ -79,8 +80,8 @@ public class ProcessWrapper {
|
||||
init();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private void init() {
|
||||
|
||||
newThread("Process OUT Stream Reader Thread",
|
||||
newProcessInputStreamReaderRunnable(process.getInputStream())).start();
|
||||
|
||||
@@ -90,15 +91,17 @@ public class ProcessWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected Runnable newProcessInputStreamReaderRunnable(InputStream in) {
|
||||
private Runnable newProcessInputStreamReaderRunnable(InputStream in) {
|
||||
|
||||
return () -> {
|
||||
|
||||
if (isRunning()) {
|
||||
|
||||
BufferedReader inputReader = new BufferedReader(new InputStreamReader(in));
|
||||
|
||||
try {
|
||||
for (String input = inputReader.readLine(); input != null; input = inputReader.readLine()) {
|
||||
for (ProcessInputStreamListener listener : listeners) {
|
||||
for (ProcessInputStreamListener listener : this.listeners) {
|
||||
listener.onInput(input);
|
||||
}
|
||||
}
|
||||
@@ -114,10 +117,10 @@ public class ProcessWrapper {
|
||||
};
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected Thread newThread(String name, Runnable task) {
|
||||
Assert.hasText(name, "Thread name must be specified");
|
||||
Assert.notNull(task, "Thread task must not be null");
|
||||
private Thread newThread(String name, Runnable task) {
|
||||
|
||||
Assert.hasText(name, "Thread name is required");
|
||||
Assert.notNull(task, "Thread task is required");
|
||||
|
||||
Thread thread = new Thread(task, name);
|
||||
|
||||
@@ -127,73 +130,62 @@ public class ProcessWrapper {
|
||||
return thread;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public boolean isAlive() {
|
||||
return ProcessUtils.isAlive(process);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public boolean isNotAlive() {
|
||||
return !isAlive();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public List<String> getCommand() {
|
||||
return processConfiguration.getCommand();
|
||||
return this.processConfiguration.getCommand();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public String getCommandString() {
|
||||
return processConfiguration.getCommandString();
|
||||
return this.processConfiguration.getCommandString();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public Map<String, String> getEnvironment() {
|
||||
return processConfiguration.getEnvironment();
|
||||
return this.processConfiguration.getEnvironment();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public int getPid() {
|
||||
return ProcessUtils.findAndReadPid(getWorkingDirectory());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public int safeGetPid() {
|
||||
|
||||
try {
|
||||
return getPid();
|
||||
}
|
||||
catch (PidUnavailableException ignore) {
|
||||
catch (PidNotFoundException ignore) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public boolean isRedirectingErrorStream() {
|
||||
return processConfiguration.isRedirectingErrorStream();
|
||||
return this.processConfiguration.isRedirectingErrorStream();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public boolean isNotRunning() {
|
||||
return !isRunning();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public boolean isRunning() {
|
||||
return ProcessUtils.isRunning(process);
|
||||
return ProcessUtils.isRunning(this.process);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public File getWorkingDirectory() {
|
||||
return processConfiguration.getWorkingDirectory();
|
||||
return this.processConfiguration.getWorkingDirectory();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public int exitValue() {
|
||||
return process.exitValue();
|
||||
return this.process.exitValue();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public int safeExitValue() {
|
||||
|
||||
try {
|
||||
return exitValue();
|
||||
}
|
||||
@@ -202,74 +194,75 @@ public class ProcessWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public String readLogFile() throws IOException {
|
||||
|
||||
File[] logFiles = FileSystemUtils.listFiles(getWorkingDirectory(),
|
||||
(path) -> (path != null && (path.isDirectory() || path.getAbsolutePath().endsWith(".log"))));
|
||||
path -> (path != null && (path.isDirectory() || path.getAbsolutePath().endsWith(".log"))));
|
||||
|
||||
if (logFiles.length > 0) {
|
||||
return readLogFile(logFiles[0]);
|
||||
}
|
||||
else {
|
||||
throw new FileNotFoundException(String.format(
|
||||
"No log files found in process's [%d] working directory [%s]",
|
||||
safeGetPid(), getWorkingDirectory()));
|
||||
throw new FileNotFoundException(String.format("No log files found in process's [%d] working directory [%s]",
|
||||
safeGetPid(), getWorkingDirectory()));
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public String readLogFile(File log) throws IOException {
|
||||
return FileUtils.read(log);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public boolean register(ProcessInputStreamListener listener) {
|
||||
return (listener != null && listeners.add(listener));
|
||||
return listener != null && listeners.add(listener);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void registerShutdownHook() {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown));
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void signal() {
|
||||
|
||||
try {
|
||||
OutputStream outputStream = process.getOutputStream();
|
||||
|
||||
OutputStream outputStream = this.process.getOutputStream();
|
||||
|
||||
outputStream.write("\n".getBytes());
|
||||
outputStream.flush();
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.warning("Failed to signal process");
|
||||
catch (IOException cause) {
|
||||
|
||||
if (log.isLoggable(Level.FINE)) {
|
||||
log.fine(ThrowableUtils.toString(e));
|
||||
this.log.warning("Failed to signal process");
|
||||
|
||||
if (this.log.isLoggable(Level.FINE)) {
|
||||
this.log.fine(ThrowableUtils.toString(cause));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void signalStop() {
|
||||
try {
|
||||
ProcessUtils.signalStop(process);
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.warning("Failed to signal the process to stop");
|
||||
|
||||
if (log.isLoggable(Level.FINE)) {
|
||||
log.fine(ThrowableUtils.toString(e));
|
||||
try {
|
||||
ProcessUtils.signalStop(this.process);
|
||||
}
|
||||
catch (IOException cause) {
|
||||
|
||||
this.log.warning("Failed to signal the process to stop");
|
||||
|
||||
if (this.log.isLoggable(Level.FINE)) {
|
||||
this.log.fine(ThrowableUtils.toString(cause));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public int stop() {
|
||||
return stop(DEFAULT_WAIT_TIME_MILLISECONDS);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public int stop(long milliseconds) {
|
||||
|
||||
if (isRunning()) {
|
||||
|
||||
boolean interrupted = false;
|
||||
int exitValue = -1;
|
||||
int pid = safeGetPid();
|
||||
@@ -279,9 +272,10 @@ public class ProcessWrapper {
|
||||
ExecutorService executorService = Executors.newSingleThreadExecutor();
|
||||
|
||||
try {
|
||||
|
||||
Future<Integer> futureExitValue = executorService.submit(() -> {
|
||||
process.destroy();
|
||||
int localExitValue = process.waitFor();
|
||||
this.process.destroy();
|
||||
int localExitValue = this.process.waitFor();
|
||||
exited.set(true);
|
||||
return localExitValue;
|
||||
});
|
||||
@@ -289,16 +283,18 @@ public class ProcessWrapper {
|
||||
while (!exited.get() && System.currentTimeMillis() < timeout) {
|
||||
try {
|
||||
exitValue = futureExitValue.get(milliseconds, TimeUnit.MILLISECONDS);
|
||||
log.info(String.format("Process [%s] has stopped%n", pid));
|
||||
this.log.info(String.format("Process [%s] has stopped%n", pid));
|
||||
}
|
||||
catch (InterruptedException ignore) {
|
||||
interrupted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (TimeoutException e) {
|
||||
catch (TimeoutException cause) {
|
||||
|
||||
exitValue = -1;
|
||||
log.warning(String.format("Process [%1$d] did not stop within the allotted timeout of %2$d seconds%n",
|
||||
|
||||
this.log.warning(String.format("Process [%1$d] did not stop within the allotted timeout of %2$d seconds%n",
|
||||
pid, TimeUnit.MILLISECONDS.toSeconds(milliseconds)));
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
@@ -319,10 +315,10 @@ public class ProcessWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public int shutdown() {
|
||||
|
||||
if (isRunning()) {
|
||||
log.info(String.format("Stopping process [%d]...%n", safeGetPid()));
|
||||
this.log.info(String.format("Stopping process [%d]...%n", safeGetPid()));
|
||||
signalStop();
|
||||
waitFor();
|
||||
}
|
||||
@@ -330,17 +326,14 @@ public class ProcessWrapper {
|
||||
return stop();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public boolean unregister(ProcessInputStreamListener listener) {
|
||||
return listeners.remove(listener);
|
||||
return this.listeners.remove(listener);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void waitFor() {
|
||||
waitFor(DEFAULT_WAIT_TIME_MILLISECONDS);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public void waitFor(long milliseconds) {
|
||||
ThreadUtils.timedWait(milliseconds, 500, this::isRunning);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user