Cannot get the getInputStream from Runtime.getRunTime.exec() - java

public class LinuxInteractor {
public static String executeCommand(String command)
{
System.out.println("Linux command: " + command);
try
{
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader bf=new BufferedReader(new InputStreamReader( p.getInputStream()));
String str=bf.readLine();
System.out.println("inputStream is::"+str);
while( (str=bf.readLine()) != null)
{
System.out.println("input stream is::"+str);
}
System.out.println("process started");
}
catch (Exception e) {
System.out.println("Error occured while executing Linux command. Error Description: "
+ e.getMessage());
e.printStackTrace();
}
}
When I run the script through console, it's working. But through Java program InputStream(Str) is coming as null.
Is there any other approach I can use?

Solution
You should try to do the reading and the executing on different threads.
A better alternative is to use a ProcessBuilder, which takes care of the "dirty" work for you.
The code inside the try block could look something like this:
/* Create the ProcessBuilder */
ProcessBuilder pb = new ProcessBuilder(commandArr);
pb.redirectErrorStream(true);
/* Start the process */
Process proc = pb.start();
System.out.println("Process started !");
/* Read the process's output */
String line;
BufferedReader in = new BufferedReader(new InputStreamReader(
proc.getInputStream()));
while ((line = in.readLine()) != null) {
System.out.println(line);
}
/* Clean-up */
proc.destroy();
System.out.println("Process ended !");
See, also, this short demo.
Cause of the problem
According to the Java Docs, waitFor():
causes the current thread to wait, if necessary, until the process represented by this Process object has terminated.
So, you are trying to get the process's output-stream after it has terminated, therefore the null.
(Sorry for the major revamp of the answer.)

You need to do this in a separate thread:
Process process = Runtime.getRuntime().exec(command);
LogStreamReader lsr = new LogStreamReader(process.getInputStream());
Thread thread = new Thread(lsr, "LogStreamReader");
thread.start();
public class LogStreamReader implements Runnable {
private BufferedReader reader;
public LogStreamReader(InputStream is) {
this.reader = new BufferedReader(new InputStreamReader(is));
}
public void run() {
try {
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Then you need a second thread for input handling. And you might want to deal with stderr just like stdout.

Related

Java 6 : ProcessBuilder inheritIO for java 6 [duplicate]

I'm building a process in Java using ProcessBuilder as follows:
ProcessBuilder pb = new ProcessBuilder()
.command("somecommand", "arg1", "arg2")
.redirectErrorStream(true);
Process p = pb.start();
InputStream stdOut = p.getInputStream();
Now my problem is the following: I would like to capture whatever is going through stdout and/or stderr of that process and redirect it to System.out asynchronously. I want the process and its output redirection to run in the background. So far, the only way I've found to do this is to manually spawn a new thread that will continuously read from stdOut and then call the appropriate write() method of System.out.
new Thread(new Runnable(){
public void run(){
byte[] buffer = new byte[8192];
int len = -1;
while((len = stdOut.read(buffer)) > 0){
System.out.write(buffer, 0, len);
}
}
}).start();
While that approach kind of works, it feels a bit dirty. And on top of that, it gives me one more thread to manage and terminate correctly. Is there any better way to do this?
Use ProcessBuilder.inheritIO, it sets the source and destination for subprocess standard I/O to be the same as those of the current Java process.
Process p = new ProcessBuilder().inheritIO().command("command1").start();
If Java 7 is not an option
public static void main(String[] args) throws Exception {
Process p = Runtime.getRuntime().exec("cmd /c dir");
inheritIO(p.getInputStream(), System.out);
inheritIO(p.getErrorStream(), System.err);
}
private static void inheritIO(final InputStream src, final PrintStream dest) {
new Thread(new Runnable() {
public void run() {
Scanner sc = new Scanner(src);
while (sc.hasNextLine()) {
dest.println(sc.nextLine());
}
}
}).start();
}
Threads will die automatically when subprocess finishes, because src will EOF.
For Java 7 and later, see Evgeniy Dorofeev's answer.
For Java 6 and earlier, create and use a StreamGobbler:
StreamGobbler errorGobbler =
new StreamGobbler(p.getErrorStream(), "ERROR");
// any output?
StreamGobbler outputGobbler =
new StreamGobbler(p.getInputStream(), "OUTPUT");
// start gobblers
outputGobbler.start();
errorGobbler.start();
...
private class StreamGobbler extends Thread {
InputStream is;
String type;
private StreamGobbler(InputStream is, String type) {
this.is = is;
this.type = type;
}
#Override
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
System.out.println(type + "> " + line);
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
A flexible solution with Java 8 lambda that lets you provide a Consumer that will process the output (eg. log it) line by line. run() is a one-liner with no checked exceptions thrown. Alternatively to implementing Runnable, it can extend Thread instead as other answers suggest.
class StreamGobbler implements Runnable {
private InputStream inputStream;
private Consumer<String> consumeInputLine;
public StreamGobbler(InputStream inputStream, Consumer<String> consumeInputLine) {
this.inputStream = inputStream;
this.consumeInputLine = consumeInputLine;
}
public void run() {
new BufferedReader(new InputStreamReader(inputStream)).lines().forEach(consumeInputLine);
}
}
You can then use it for example like this:
public void runProcessWithGobblers() throws IOException, InterruptedException {
Process p = new ProcessBuilder("...").start();
Logger logger = LoggerFactory.getLogger(getClass());
StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(), System.out::println);
StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), logger::error);
new Thread(outputGobbler).start();
new Thread(errorGobbler).start();
p.waitFor();
}
Here the output stream is redirected to System.out and the error stream is logged on the error level by the logger.
It's as simple as following:
File logFile = new File(...);
ProcessBuilder pb = new ProcessBuilder()
.command("somecommand", "arg1", "arg2")
processBuilder.redirectErrorStream(true);
processBuilder.redirectOutput(logFile);
by .redirectErrorStream(true) you tell process to merge error and output stream and then by .redirectOutput(file) you redirect merged output to a file.
Update:
I did manage to do this as follows:
public static void main(String[] args) {
// Async part
Runnable r = () -> {
ProcessBuilder pb = new ProcessBuilder().command("...");
// Merge System.err and System.out
pb.redirectErrorStream(true);
// Inherit System.out as redirect output stream
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
try {
pb.start();
} catch (IOException e) {
e.printStackTrace();
}
};
new Thread(r, "asyncOut").start();
// here goes your main part
}
Now you're able to see both outputs from main and asyncOut threads in System.out
There is a library that provides a better ProcessBuilder, zt-exec. This library can do exactly what you are asking for and more.
Here's what your code would look like with zt-exec instead of ProcessBuilder :
add the dependency :
<dependency>
<groupId>org.zeroturnaround</groupId>
<artifactId>zt-exec</artifactId>
<version>1.11</version>
</dependency>
The code :
new ProcessExecutor()
.command("somecommand", "arg1", "arg2")
.redirectOutput(System.out)
.redirectError(System.err)
.execute();
Documentation of the library is here : https://github.com/zeroturnaround/zt-exec/
Simple java8 solution with capturing both outputs and reactive processing using CompletableFuture:
static CompletableFuture<String> readOutStream(InputStream is) {
return CompletableFuture.supplyAsync(() -> {
try (
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
) {
StringBuilder res = new StringBuilder();
String inputLine;
while ((inputLine = br.readLine()) != null) {
res.append(inputLine).append(System.lineSeparator());
}
return res.toString();
} catch (Throwable e) {
throw new RuntimeException("problem with executing program", e);
}
});
}
And the usage:
Process p = Runtime.getRuntime().exec(cmd);
CompletableFuture<String> soutFut = readOutStream(p.getInputStream());
CompletableFuture<String> serrFut = readOutStream(p.getErrorStream());
CompletableFuture<String> resultFut =
soutFut.thenCombine(serrFut, (stdout, stderr) -> {
// print to current stderr the stderr of process and return the stdout
System.err.println(stderr);
return stdout;
});
// get stdout once ready, blocking
String result = resultFut.get();
I too can use only Java 6. I used #EvgeniyDorofeev's thread scanner implementation. In my code, after a process finishes, I have to immediately execute two other processes that each compare the redirected output (a diff-based unit test to ensure stdout and stderr are the same as the blessed ones).
The scanner threads don't finish soon enough, even if I waitFor() the process to complete. To make the code work correctly, I have to make sure the threads are joined after the process finishes.
public static int runRedirect (String[] args, String stdout_redirect_to, String stderr_redirect_to) throws IOException, InterruptedException {
ProcessBuilder b = new ProcessBuilder().command(args);
Process p = b.start();
Thread ot = null;
PrintStream out = null;
if (stdout_redirect_to != null) {
out = new PrintStream(new BufferedOutputStream(new FileOutputStream(stdout_redirect_to)));
ot = inheritIO(p.getInputStream(), out);
ot.start();
}
Thread et = null;
PrintStream err = null;
if (stderr_redirect_to != null) {
err = new PrintStream(new BufferedOutputStream(new FileOutputStream(stderr_redirect_to)));
et = inheritIO(p.getErrorStream(), err);
et.start();
}
p.waitFor(); // ensure the process finishes before proceeding
if (ot != null)
ot.join(); // ensure the thread finishes before proceeding
if (et != null)
et.join(); // ensure the thread finishes before proceeding
int rc = p.exitValue();
return rc;
}
private static Thread inheritIO (final InputStream src, final PrintStream dest) {
return new Thread(new Runnable() {
public void run() {
Scanner sc = new Scanner(src);
while (sc.hasNextLine())
dest.println(sc.nextLine());
dest.flush();
}
});
}
It's really surprising to me that the redirection methods in ProcessBuilder don't accept an OutputStream, only File. Yet another proof of forced boilerplate code that Java forces you to write.
That said, let's look at a list of comprehensive options:
If you want the process output to simply be redirected to its parent's output stream, inheritIO will do the job.
If you want the process output to go to a file, use redirect*(file).
If you want the process output to go to a logger, you need to consume the process InputStream in a separate thread. See the answers that use a Runnable or CompletableFuture. You can also adapt the code below to do this.
If you want to the process output to go to a PrintWriter, that may or may not be the stdout (very useful for testing), you can do the following:
static int execute(List<String> args, PrintWriter out) {
ProcessBuilder builder = new ProcessBuilder()
.command(args)
.redirectErrorStream(true);
Process process = null;
boolean complete = false;
try {
process = builder.start();
redirectOut(process.getInputStream(), out)
.orTimeout(TIMEOUT, TimeUnit.SECONDS);
complete = process.waitFor(TIMEOUT, TimeUnit.SECONDS);
} catch (IOException e) {
throw new UncheckedIOException(e);
} catch (InterruptedException e) {
LOG.warn("Thread was interrupted", e);
} finally {
if (process != null && !complete) {
LOG.warn("Process {} didn't finish within {} seconds", args.get(0), TIMEOUT);
process = process.destroyForcibly();
}
}
return process != null ? process.exitValue() : 1;
}
private static CompletableFuture<Void> redirectOut(InputStream in, PrintWriter out) {
return CompletableFuture.runAsync(() -> {
try (
InputStreamReader inputStreamReader = new InputStreamReader(in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader)
) {
bufferedReader.lines()
.forEach(out::println);
} catch (IOException e) {
LOG.error("Failed to redirect process output", e);
}
});
}
Advantages of the code above over the other answers thus far:
redirectErrorStream(true) redirects the error stream to the output stream, so that we only have to bother with one.
CompletableFuture.runAsync runs from the ForkJoinPool. Note that this code doesn't block by calling get or join on the CompletableFuture but sets a timeout instead on its completion (Java 9+). There's no need for CompletableFuture.supplyAsync because there's nothing really to return from the method redirectOut.
BufferedReader.lines is simpler than using a while loop.
As an addition to msangel answer I would like to add the following code block:
private static CompletableFuture<Boolean> redirectToLogger(final InputStream inputStream, final Consumer<String> logLineConsumer) {
return CompletableFuture.supplyAsync(() -> {
try (
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
) {
String line = null;
while((line = bufferedReader.readLine()) != null) {
logLineConsumer.accept(line);
}
return true;
} catch (IOException e) {
return false;
}
});
}
It allows to redirect the input stream (stdout, stderr) of the process to some other consumer. This might be System.out::println or anything else consuming strings.
Usage:
...
Process process = processBuilder.start()
CompletableFuture<Boolean> stdOutRes = redirectToLogger(process.getInputStream(), System.out::println);
CompletableFuture<Boolean> stdErrRes = redirectToLogger(process.getErrorStream(), System.out::println);
System.out.println(stdOutRes.get());
System.out.println(stdErrRes.get());
System.out.println(process.waitFor());
Thread thread = new Thread(() -> {
new BufferedReader(
new InputStreamReader(inputStream,
StandardCharsets.UTF_8))
.lines().forEach(...);
});
thread.start();
Your custom code goes instead of the ...
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws Exception {
ProcessBuilder pb = new ProcessBuilder("script.bat");
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader logReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String logLine = null;
while ( (logLine = logReader.readLine()) != null) {
System.out.println("Script output: " + logLine);
}
}
}
By using this line: pb.redirectErrorStream(true); we can combine InputStream and ErrorStream
By default, the created subprocess does not have its own terminal or console. All its standard I/O (i.e. stdin, stdout, stderr) operations will be redirected to the parent process, where they can be accessed via the streams obtained using the methods getOutputStream(), getInputStream(), and getErrorStream(). The parent process uses these streams to feed input to and get output from the subprocess. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, or even deadlock.
https://www.securecoding.cert.org/confluence/display/java/FIO07-J.+Do+not+let+external+processes+block+on+IO+buffers

Detecting terminal command errors in Java

In my Java application I am using the exec() command to call a terminal function:
p = Runtime.getRuntime().exec(command);
p.waitFor();
The call uses the zip and unzip calls. Originally I call:
zip -P password -r encrypted.zip folderIWantToZip
When I call the unzip function through java, I specify the password as the method parameter. If the correct password is specified then the call should unzip the encrypted folder:
unzip -P password encrypted.zip
I want a way to find out if the password entered is incorrect. For example, if password is correct, then the call will correctly unzip the zip file. But I notice that no exception is thrown for an incorrect password. How can I determine this?
You could read the process's ErrorStream and InputStream to determine the process output. Sample code given below
public static void main(String[] args) {
try {
String command = "zip -P password -r encrypted.zip folderIWantToZip";
Process p = Runtime.getRuntime().exec(command);
InputStream is = p.getInputStream();
int waitFor = p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = reader.readLine()) != null) {
System.out.println("line:" + line);
}
is = p.getErrorStream();
reader = new BufferedReader(new InputStreamReader(is));
while ((line = reader.readLine()) != null) {
System.out.println("ErrorStream:line: " + line);
}
System.out.println("waitFor:" + waitFor);
System.out.println("exitValue:" + p.exitValue());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You could use the exitcode to validate the process status as well but it is specific to to program. Normally zero means successfully terminated otherwise abnormal termination.
As per my comment, first thing I would do would be to capture the Process's InputStream and ErrorStream via getInputStream() and getErrorStream(), but especially the latter, the ErrorStream, and check to see what it outputs if the input is in error. Note that these would have to be done in their own thread, else you'll tie up your program. I usually use some type of StreamGobbler class for this. Also, don't ignore the int returned by p.waitFor().
e.g.,
ProcessBuilder pBuilder = new ProcessBuilder(COMMAND);
Process process = null;
try {
process = pBuilder.start();
new Thread(new StreamGobbler("Input", process.getInputStream())).start();
new Thread(new StreamGobbler("Error", process.getErrorStream())).start();
int exitValue = process.waitFor();
System.out.println("Exit Value: " + exitValue);
process.destroy();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (process != null) {
process.destroy();
}
}
And:
class StreamGobbler implements Runnable {
private String name;
private Scanner scanner;
public StreamGobbler(String name, InputStream inputStream) {
this.name = name;
scanner = new Scanner(inputStream);
}
#Override
public void run() {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(name + ": " + line); // or better, log the line
}
scanner.close();
}
}

Runtime Process BufferedReader not outputting all lines (Psexec)

I am trying to read the output of Psexec into Java using a BufferedReader on a Process InputStream for use on a network however it is only outputting the first line.
Runtime rt = Runtime.getRuntime();
try {
Process p = rt.exec("C:\\Users\\*****\\Desktop\\PS\\Psexec \\\\" + "******" + " -u ****** -p ****** cmd /c dir D:\\");
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
log.add("Computer: " + address);
String s = null;
while ((s = stdInput.readLine()) != null) {
log.add(s);
}
} catch (IOException e) {
e.printStackTrace();
}
What would be the reason for this happening and how would this be fixed?
The process is probably producing some of its output on stderr. Either read both the output and the error streams, in separate threads, or use the ProcessBuilder to create the Process, and merge the output streams before you do so, with redirectErrorStream().
So, I spent some time playing around with this, using ProcessBuilder.
I tried redirecting the IO through the INHERITED and PIPE options, but could not get it to display the output of the remote command (the psexec content was fine)
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class Test1 {
public static void main(String[] args) {
ProcessBuilder pb = new ProcessBuilder(
"C:\\Users\\shane\\Downloads\\PSTools\\PsExec.exe",
"\\\\builder",
"-u",
"xxx",
"-p",
"xxx",
"cmd",
"/c", "dir", "c:\\"
);
try {
Process p = pb.start();
StreamConsumer.consume(p.getErrorStream());
StreamConsumer.consume(p.getInputStream());
System.out.println("Exited with :" + p.waitFor());
} catch (IOException | InterruptedException exp) {
exp.printStackTrace();
}
}
public static class StreamConsumer implements Runnable {
private InputStream is;
public StreamConsumer(InputStream is) {
this.is = is;
}
public static void consume(InputStream is) {
StreamConsumer consumer = new StreamConsumer(is);
new Thread(consumer).start();
}
#Override
public void run() {
try {
int in = -1;
while ((in = is.read()) != -1) {
System.out.print((char)in);
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
}
I even tried redirecting the InputStreams to File without any success. It would seem that whatever mechanism psexec is using to stream the results from the remote machine don't seem to be picked up by Java.
You might try PAExec which did work, but didn't seem to wait to exit after the remote command exited...
It could be the case that you started the process and didn't wait for it to finish before checking it's output. If this is the case, your main thread will exit your while loop because it reads null even though the subprocess is still executing. I would suggest using Process.waitFor() so that all of the output ends up in the stream before you begin polling it.

Java Process stops in the middle of the process

I've been trying to google this around for quite a while now, without any success. I'm hoping to get my issue solved here.
First function:
public void startTFServer(Channel c) {
try {
ProcessBuilder procBuilder = new ProcessBuilder("tfs.exe");
procBuilder.redirectErrorStream();
Process proc = null;
System.out.println(Runtime.getRuntime().freeMemory());
proc = procBuilder.start();
System.out.println(Runtime.getRuntime().freeMemory());
StreamGobbler gobbler = new StreamGobbler(proc.getInputStream(), "STD_OUT");
gobbler.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The thread that captures the process output:
private class StreamGobbler extends Thread {
InputStream is;
String type;
private StreamGobbler(InputStream is, String type) {
this.is = is;
this.type = type;
}
#Override
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(type + "> " + line);
}
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
The problem:
When running the application the input interrupts at the same place every time. The application I'm running with the "Process class" is a server that required quite some memory to run, can this be one of the reasons for why the process won't finish loading my app? I was thinking that the memory would run out, but I can't really diagnostise it.
Any help would be greatly appreciated!
There is one issues that I notice:
procBuilder.redirectErrorStream();
This is not what you want. This is a getter method which tells you what the value of the redirectErrorStream property is. It could possibly be that you have errors and you are blocked because they are not read. Therefore, you need to use the setter method: see the API redirectErrorStream(boolean)
procBuilder.redirectErrorStream(true);
I'm guessing so sorry if I'm wrong, but I think you are exhausting the output from the external process, not waiting until it finishes in order to keep reading. I mean, basically:
while ((line = br.readLine()) != null) {
System.out.println(type + "> " + line);
}
If the process stops writing to the output for a second, your logger will stop logging. If it starts writing again, you will be out of the loop.

Reading streams from java Runtime.exec

I have the following snippet of code:
Process proc = runtime.exec(command);
errorGobbler = new ErrorStreamGobbler(proc.getErrorStream(), logErrors, mdcMap);
outputGobbler = new OutputStreamGobbler(proc.getInputStream(), mdcMap);
executor.execute(errorGobbler);
executor.execute(outputGobbler);
processExitCode = proc.waitFor();
where the gobblers are Runnables which use a BufferedReader to read the input and error streams of the executing process. While this works most of the time, I get the occasional window (of about 2 minutes or so) where I get the processExitCode as 0, which indicates normal termination but there is nothing in the input and error streams - nothing to even indicate end-of-stream.
Like I indicated before, this works most of the time but this failure occurs every once in a while - and I am totally puzzled. Any ideas?
Rags
I've struggled with the same kind of issues.
I can't remember what exactly was wrong (maybe I forgot to flush / close the streams correctly or something ...).
Anyway, here is what I came up with.
/**
* Handle communication with a process, reading its output/error and feeding its input
* #param process The process to execute
* #param _in Reader that will feed the input pipe of the process
* #param out Writer that will receive the output of the process
* #param err Writer that will receive the error pipe of the process
*/
public static void communicate(
Process process,
final Reader _in,
final Writer out,
final Writer err)
{
// Buffer the input reader
final BufferedReader in = new BufferedReader(_in);
// Final versions of the the params, to be used within the threads
final BufferedReader stdOut = new BufferedReader(new InputStreamReader(process.getInputStream()));
final BufferedReader stdErr = new BufferedReader(new InputStreamReader(process.getErrorStream()));
final BufferedWriter stdIn = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
// Thread that reads std out and feeds the writer given in input
new Thread() {
#Override public void run() {
String line;
try {
while ((line = stdOut.readLine()) != null) {
out.write(line + newline);
}
} catch (Exception e) {throw new Error(e);}
try {
out.flush();
out.close();
} catch (IOException e) { /* Who cares ?*/ }
}
}.start(); // Starts now
// Thread that reads std err and feeds the writer given in input
new Thread() {
#Override public void run() {
String line;
try {
while ((line = stdErr.readLine()) != null) {
err.write(line + newline);
}
} catch (Exception e) {throw new Error(e);}
try {
err.flush();
err.close();
} catch (IOException e) { /* Who cares ?*/ }
}
}.start(); // Starts now
// Thread that reads the std in given in input and that feeds the input of the process
new Thread() {
#Override public void run() {
String line;
try {
while ((line = in.readLine()) != null) {
stdIn.write(line + newline);
}
} catch (Exception e) {throw new Error(e);}
try {
stdIn.flush();
stdIn.close();
} catch (IOException e) { /* Who cares ?*/ }
}
}.start(); // Starts now
// Wait until the end of the process
try {
process.waitFor();
} catch (Exception e) {
throw new Error(e);
}
} // End of #communicate
I hope this helps.

Categories