So... this is rather a loaded question, although that might not be obvious from just asking it.
I was not able to do this using the ProcessBuilder
class
(maybe someone with more experience can answer using that route).
Here is what you need to do: use the class Runtime.getRuntime().exec(command)
to run your command. This gives you easy access to the standard input and standard error streams.
Below is a general complete class you can use.
Usage:
final String jarPath = "jarPath.jar";
final String[] command = { "java.exe", "-jar", jarPath };
final CrossPlatformCommand childProcess = new CrossPlatformCommand();
final int exitCode = childProcess.execute(command[0] + " " + command[1] + " " + command[2]);
System.out.println("Parse child process output: " + childProcess.getInput());
Output:
Parse child process output: Success!
There are a few caveats with this: the dollar sign needs to be escaped in Linux. There may be other characters that need to be escaped (this has not been investigated fully, and you may need to modify this class if you are using other characters that need to be escaped.)
public class CrossPlatformCommand
{
private static final String SHELL_LINUX = "/bin/bash";
private static final int BUFFER_SIZE = 4096;
private static final String OS_NAME = System.getProperty("os.name").toLowerCase(Locale.getDefault());
private final StringBuffer error = new StringBuffer();
private final StringBuffer input = new StringBuffer();
public int execute(final String command) throws Exception
{
final int exitCode;
if (OS_NAME.startsWith("windows"))
{
exitCode = executeWindows(command);
}
else
{
exitCode = executeLinux(command); // OS_NAME.startsWith("linux")
}
return exitCode;
}
public String getError()
{
return this.error.toString();
}
public String getInput()
{
return this.input.toString();
}
private int executeLinux(final String command) throws Exception
{
final Process proc = Runtime.getRuntime().exec(SHELL_LINUX);
processLinuxCommand(proc, command);
return processStreams(proc);
}
private int executeWindows(final String command) throws Exception
{
final Process proc = Runtime.getRuntime().exec(command);
return processStreams(proc);
}
private static void processLinuxCommand(final Process proc, final String command) throws Exception
{
try (BufferedWriter out = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())))
{
// Dollar signs are special in Linux.
out.write(command.replace("$", "\\$"));
out.newLine();
out.flush();
}
}
private int processStreams(final Process proc) throws Exception
{
fillBuffer(proc.getInputStream(), this.input);
fillBuffer(proc.getErrorStream(), this.error);
return proc.waitFor();
}
private static void fillBuffer(final InputStream in, final StringBuffer sb) throws IOException
{
sb.setLength(0);
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
final char[] buffer = new char[BUFFER_SIZE];
final int length = reader.read(buffer);
for (int i = 0; i < length; i++)
{
sb.append(buffer[i]);
}
}
}