Process p = Runtime.getRuntime().exec("myexe.exe");
BufferedReader br = null;
try{
br = new BufferedReader(new InputStreamReader(p.getInputStream(), "GB2312"));
String value = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}finally{
IOUtils.close(br);
}
Then, the output likes below, not the string I want:
Child: Can't read length for data, error code 109
It seems that the problem appears, because of the output of the exe which is too long. Can ProcessBuilder solve it ?
As a general rule of thumb, you should always read the output of Process before you call waitFor (or use a background Thread to read it while you waitFor)
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class PBDemo {
public static void main(String[] args) throws Exception {
String s;
ProcessBuilder pb = new ProcessBuilder("myexe.exe");
pb.redirectErrorStream(true);
try {
Process pro = pb.start();
InputConsumer ic = new InputConsumer(pro.getInputStream());
System.out.println("...Waiting");
int exitCode = pro.waitFor();
ic.join();
System.out.println("Process exited with " + exitCode);
} catch (Exception e) {
System.out.println("sorry" + e);
e.printStackTrace();
}
}
public static class InputConsumer extends Thread {
private InputStream is;
public InputConsumer(InputStream is) {
this.is = is;
start();
}
#Override
public void run() {
try {
int in = -1;
while ((in = is.read()) != -1) {
System.out.print((char) in);
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
}
In the past, I've either provided an Observer Pattern to the InputConsumer, through which some other party can be notified as new input comes in or otherwised cached the output so I can process it after the process has completed, based on your needs
Related
I'm trying to get the result from a .class, calling the process on another .java. The formatting of both files is as follows:
package Ejemplo2;
import java.io.*;
public class Ejemplo2 {
public static void main(String[] args) throws IOException {
Process p = new ProcessBuilder("ls", "-la").start();
try {
InputStream is = p.getInputStream();
int c;
while ((c = is.read()) != -1) {
System.out.print((char) c);
}
is.close();
} catch (Exception e) {
e.printStackTrace();
}
int exitVal;
try {
exitVal = p.waitFor(); //recoge la salida de System.exit()
System.out.println("Valor de Salida: " +exitVal);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
and
package Ejemplo3;
import java.io.*;
public class Ejemplo3 {
public static void main(String[] args) throws IOException{
File directorio = new File("./out/production/psp-2122/Ejemplo2");
ProcessBuilder pb = new ProcessBuilder("java", "Ejemplo2");
pb.directory(directorio);
System.out.printf("Directorio de trabajo: %s%n",pb.directory());
Process p = pb.start();
try {
InputStream is = p.getInputStream();
for (int i = 0; i<is.available(); i++) {
System.out.println("" + is.read());
}
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The result only displays the directory and the exit code, but I don't really have a clue why the process itself is not shown.
You should probably do:
// start in classes root
File directorio = new File("./out/production/psp-2122");
// Run java with fully qualified class name Ejemplo2.Ejemplo2
ProcessBuilder pb = new ProcessBuilder("java", "Ejemplo2.Ejemplo2");
You aren't seeing any of the error messages as you are not reading any of the error streams. The simplest approach is to just redirect standard ERROR -> OUTPUT before calling start():
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
Process p = pb.start();
Save yourself some typing, replace the while / for loops through the standard output streams with:
try(var stdout = p.getInputStream()) {
stdout.transferTo(System.out);
}
Always call waitFor at the end so that you know the process completion:
int exitVal = pb.waitFor();
This question already has answers here:
run interactive command line application from java
(2 answers)
Closed 6 years ago.
Basically, I have a process which runs when I press a button on my java application.
And this process executes a command to the terminal of the OS.
But sometimes this command needs to have an interaction with the user.
And I would like to know if this was possible to have the interaction from the process to the user when needed?
My code:
File marsSimulator = new File("resources/mars_simulator/Mars4_5.jar");
if(marsSimulator.exists() && temp.exists()){
String res="";
try {
Process p = Runtime.getRuntime().exec(new String[]{"java","-jar",marsSimulator.getAbsolutePath(),tempAssembly.getAbsolutePath()});
p.waitFor();
InputStream is = p.getInputStream();
byte b[] = new byte[is.available()];
is.read(b, 0, b.length); // probably try b.length-1 or -2 to remove "new-line(s)"
res = new String(b);
} catch (Exception ex) {
ex.printStackTrace();
}
}
Also, I forgot to say that the application is made with SWING and that the output of the process is shown onto a TextArea... Should I change anything ?
Notice that the process blocks when there is an interaction with the user. If there isn't, the process doesn't block !
What do I need to do in this case (which I don't know how to do it ) ?
When the process needs the interaction. I need to know when the process wants some interaction.
I need to get the output generated of the process interactively (line by line).
P.S.: For people who wanna understand the process line, I am using the Mars Simulator (http://courses.missouristate.edu/KenVollmar/MARS/) and I am sending the jar application into a process with a mips assembly code associated.
This next pieces of code is working with my project
Hope it will help for the next adventurers!
And thank you to Nicolas Filotto for helping me.
My class ObservableStream:
class ObservableStream extends Observable {
private final Queue<String> lines = new ConcurrentLinkedQueue<>();
public void addLine(String line) {
lines.add(line);
setChanged();
notifyObservers();
}
public String nextLine() {
return lines.poll();
}
public String getLine(){return lines.peek();}
}
And the other part of the code:
Process p = Runtime.getRuntime().exec(new String[]{"java","-jar",marsSimulator.getAbsolutePath(),tempAssembly.getAbsolutePath()});
//This code does the interaction from the process with the GUI ! Implied, input interaction+output interaction from the process
ObservableStream out = new ObservableStream();
// Observer that simply sends to my external process line by line what we put in
// the variable output
PrintWriter writer = new PrintWriter(p.getOutputStream(), true);
out.addObserver(
(o, arg) -> {
ObservableStream stream = (ObservableStream) o;
String line;
while ((line = stream.nextLine()) != null) {
writer.println(line);
}
}
);
ObservableStream input = new ObservableStream();
input.addObserver(
(o, arg) -> {
ObservableStream stream = (ObservableStream) o;
String line;
while ((line = stream.nextLine()) != null) {
outputTextArea.appendText(line+"\n");
}
}
);
// The thread that reads the standard output stream of the external process
// and put the lines into my variable input
new Thread(
() -> {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getInputStream()))
) {
String line;
while ((line = reader.readLine()) != null) {
input.addLine(line);
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
).start();
new Thread(
()->{
while(p.isAlive()){
String res = input.getLine();
if(res!=null && res.equals("Enter integer value:")) {
boolean integerIsRequested=true;
Thread t=null;
while(integerIsRequested){
if(t==null) {
t = new Thread(new Runnable() {
public void run() {
String test1 = JOptionPane.showInputDialog("Enter Integer value:");
while(!test1.matches("^\\d+$")){
test1 = JOptionPane.showInputDialog("Error: Not a valid Integer.\nEnter a correct Integer value:");
}
Integer i = Integer.valueOf(test1);
if (i != null) {
out.addLine(test1);
}
}
});
t.start();
}
if(!t.isAlive()){
integerIsRequested=false;
}
}
}
}
outputTextArea.appendText("Program executed\n");
}
).start();
By the way, this post is unique Jarrod ;)
To implement such use case I would personally use:
An Observable object to notify my UI when a new line has been provided by the external process
An Observable object to which I add new lines provided by my UI
An Observer of #1 that will refresh the data of my UI
An Observer of #2 that will send the lines provided by my UI to my external process
A Thread that will check if a new line has been provided by my external process and if so it will provide those lines to #1
So as I don't have your full env, I will show you how it will work with mock objects:
First my fake external application that only does an Echo of what he receives:
public class Echo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
String line = scanner.nextLine();
System.out.printf("echo > %s%n", line);
}
}
}
If this class receives foo, it will print into the standard output stream echo > foo
Then my Observable class
public class ObservableStream extends Observable {
private final Queue<String> lines = new ConcurrentLinkedQueue<>();
public void addLine(String line) {
lines.add(line);
setChanged();
notifyObservers();
}
public String nextLine() {
return lines.poll();
}
}
NB: The class ObservableStream (as it is implemented so far) is meant to have only one Observer no more which is enough according to your needs. Indeed is only used to decouple your UI from how the data is retrieved or published
Then finally the main code:
Process p = Runtime.getRuntime().exec(
new String[]{"java", "-cp", "/my/path/to/my/classes", "Echo"}
);
// The Observable object allowing to get the input lines from my external process
ObservableStream input = new ObservableStream();
// A mock observer that simply prints the lines provided by the external process
// but in your case you will update your text area instead
input.addObserver(
(o, arg) -> {
ObservableStream stream = (ObservableStream) o;
String line;
while ((line = stream.nextLine()) != null) {
System.out.printf("Line Received from the external process: %s%n", line);
}
}
);
// The thread that reads the standard output stream of the external process
// and put the lines into my variable input
new Thread(
() -> {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getInputStream()))
) {
String line;
while ((line = reader.readLine()) != null) {
input.addLine(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
).start();
// The Observable object allowing to send the input lines to my external process
ObservableStream output = new ObservableStream();
// Observer that simply sends to my external process line by line what we put in
// the variable output
PrintWriter writer = new PrintWriter(p.getOutputStream(), true);
output.addObserver(
(o, arg) -> {
ObservableStream stream = (ObservableStream) o;
String line;
while ((line = stream.nextLine()) != null) {
writer.println(line);
}
}
);
// A simple scanner used to send new messages to my external process
Scanner scanner = new Scanner(System.in);
while (true) {
output.addLine(scanner.nextLine());
}
If this code receives foo, it will print into the standard output stream Line Received from the external process: echo > foo
I hope it answers your question... subProcessStuff "emulates" that sub process. It can be anything - but this way we have all in place. It requires 2 params passed into console. String and Integer. Gobbler got Callback which is an interface, with anonymous implementation - and there are checks for params. To answer if subprocess waits we simply track what is says - just like if a user would operate with it.
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Scanner;
class Test1 {
public static void main(String[] args) {
for (String arg : args)
System.out.println("arg: " + arg);
for (String arg : args)
if (arg.equals("-test")) {
subProcessStuff();
return;
}
mainProcess();
}
public static void subProcessStuff() {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
System.out.println("Enter String");
String s = br.readLine();
System.out.println("Enered String: " + s);
System.out.println("Enter Integer:");
int i = Integer.parseInt(br.readLine());
System.out.println("Entered Integer: " + i);
} catch (IOException e) {
System.err.println("io error - " + e.getMessage());
} catch (NumberFormatException nfe) {
System.err.println("Invalid Format!");
}
}
private static PrintStream out;
public static void mainProcess() {
String[] commands = { "ls", "-alt" };
ProcessBuilder builder = new ProcessBuilder("java", "Test1", "-test");
// builder.inheritIO(); // I avoid this. It was messing me up.
try {
Process proc = builder.start();
InputStream errStream = proc.getErrorStream();
InputStream inStream = proc.getInputStream();
OutputStream outStream = proc.getOutputStream();
new Thread(new StreamGobbler("err", out, errStream)).start();
out = new PrintStream(new BufferedOutputStream(outStream));
Callback cb = new Callback() {
#Override
public void onNextLine(String line) {
if (line.equals("Enter String")) {
out.println("aaaaa");
out.flush();
}
if (line.equals("Enter Integer:")) {
out.println("123");
out.flush();
}
}
};
new Thread(new StreamGobbler("in", out, inStream, cb)).start();
int errorCode = proc.waitFor();
System.out.println("error code: " + errorCode);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
}
}
interface Callback {
void onNextLine(String line);
}
class StreamGobbler implements Runnable {
private PrintStream out;
private Scanner inScanner;
private String name;
private Callback cb;
public StreamGobbler(String name, PrintStream out, InputStream inStream) {
this.name = name;
this.out = out;
inScanner = new Scanner(new BufferedInputStream(inStream));
}
public StreamGobbler(String name, PrintStream out, InputStream inStream, Callback cb) {
this.name = name;
this.out = out;
inScanner = new Scanner(new BufferedInputStream(inStream));
this.cb = cb;
}
#Override
public void run() {
while (inScanner.hasNextLine()) {
String line = inScanner.nextLine();
if (cb != null)
cb.onNextLine(line);
System.out.printf("%s: %s%n", name, line);
}
}
}
I don't think you can check the state of the process from the Java. However you can do it by using some Linux command. (Of course if you're using Linux)
If your Java process has access to the /proc directory then you can read the status file for the process.
For example for a process with process id 12280
/proc/12280/status
Here's the relevant output of the status file
Name: java
State: S (sleeping)
Tgid: 12280
Pid: 12280
PPid: 12279
...
Second line gives the state of the process. You'll need to run a thread to continuously poll this file to read the status.
Line by Line The Code i use to interract with a different jar which is a speechRecognizer.I think you want to achieve something like this.
Example:
The jar i am interracting(speechRecognizer) is executing different commands and run some other Threads.Every time it has to interract with the main jar it prints something that i need.For example (user said:How are you),so you can have a same logic and when external jar need interraction with user it prints something and you read it into the main app.So:
// About Process
private Process process;
private BufferedReader bufferedReader;
private boolean stopped = true;
Thread processChecker;
//Running it in a Thread so the app don't lags
new Thread(() -> {
try {
stopped = false;
//Starting the external jar..
ProcessBuilder builder = new ProcessBuilder("java", "-jar", System.getProperty("user.home")
+ File.separator + "Desktop" + File.separator + "speechRecognizer.jar", "BITCH_PLEASE");
//Redirecting the ErrorStream
builder.redirectErrorStream(true);
process = builder.start();
bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
//Check continusly if the process is still alive
//i case of crash i should do something..
processChecker = new Thread(() -> {
while (process.isAlive()) {
try {
Thread.sleep(1200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
stopSpeechReader(false);
});
processChecker.start();
// Continuesly Read Output of external process
while (!stopped) {
while ((line = bufferedReader.readLine()) != null && !line.isEmpty()) {
System.out.println(line);
checkSpeechResult(line);
}
}
// Interrupt the mf Thread if is Alive
if (processChecker.isAlive())
processChecker.interrupt();
System.out.println("SpeechReader Stopped! Process is alive:" + process.isAlive() + " >Exit Value:"
+ process.exitValue());
} catch (Exception e) {
e.printStackTrace();
}
}).start();
I have a problem. Need to redirect process.getErrorStream(), process.getInputStream() and process.getOutputStream() to JTextPane.
Process is situated in class A, and JTextPane is situated in class B, so there isn't direct connection between them. For this purpose I've create interface. So, I can call method informListener(String message) which appends line to JTextPane. But I can't find any solution which can solve my problem. Are there any nice and easy solutions?
Thanks.
What you need is couple of threads that read the data from the input streams returned by get*Stream methods and append into the text area.
Something like:
final BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream());
new Thread(new Runnable() {
String line ;
while ((line = reader.readLine()) != null) {
interfaceObject.informListener(line);
}
}).start();
Just ensure that the appending to textPane happens in EDT using SwingUtilities.invokeLater.
The following program works. (I am on OS X):
package snippet;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ProcessOutput {
public static void main(String[] args) throws IOException, InterruptedException {
final Process p = Runtime.getRuntime().exec("ls -lR");
final BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
new Thread(new Runnable() {
#Override public void run() {
try {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException ex) {
}
}
}).start();
int waitFor = p.waitFor();
System.out.println(waitFor + " is the return");
}
}
Check whether your command is being constructed properly. May be just print it out and see whether you are able to execute it from cmdline.
It doesn't work. InformaListener calls another method. Here is it's code:
HTMLEditorKit kit = new HTMLEditorKit();
HTMLDocument doc = new HTMLDocument();
...
logTextPane.setEditorKit(kit);
logTextPane.setDocument(doc);
public void onLogData(final String message) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
kit.insertHTML(doc, doc.getLength(), message, 0, 0, null);
} catch (BadLocationException ex) {
Logger.getLogger(SummaryPanel.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(SummaryPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
And here is code to getErrorStream:
final String exec = "cmd /C start " + batStrPath + "\\upgrade-build.bat";
final Process p = Runtime.getRuntime().exec(exec);
final BufferedReader reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
new Thread(new Runnable() {
#Override
public void run() {
try {
String line ;
while ((line = reader.readLine()) != null) {
informListener(line);
}
} catch (IOException ex) {
Logger.getLogger(Installer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}).start();
p.waitFor();
I've spent the past 3 days without much luck on google on how to run a grep process from within Java.
I have the following code to run a grep process, however, I am only getting the first line of the response.
package com.example.parser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) {
try {
Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/").start();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
while((line = br.readLine()) != null) {
System.out.println(line);
}
System.out.println("Exit Code: " + process.exitValue());
} catch (IOException e) {
e.printStackTrace();
}
}
}
I am only getting the following response:
Binary file /home/user/dev/java/Parser/parser/bin/com/example/parser/Main.class matches
Exit Code: 0
When I should be getting the following response:
Binary file /home/user/dev/java/Parser/parser/com/example/parser/Main.class matches
/home/user/dev/java/Parser/parser/src/com/example/parser/Main.java:10: public static void main(String[] args) {
/home/user/dev/java/Parser/parser/src/com/example/parser/Main.java:12: Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/Parser/parser").start();
Exit Code: 0
I am wondering why I only get output for the first finding? Is grep forking several processes to run the search and I'm only getting a handle on the first one?
I have also tried running the process from a Thread:
package com.example.parser;
public class Main {
public static void main(String[] args) {
try {
Analyzer analyzer = new Analyzer();
analyzer.start();
analyzer.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.example.parser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Analyzer extends Thread {
public Analyzer() {
}
#Override
public void run() {
try {
Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/Parser/parser").start();
process.waitFor();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
while((line = br.readLine()) != null) {
System.out.println(line);
}
System.out.println("Exit Code: " + process.exitValue());
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
As well as the following:
package com.example.parser;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/Parser/parser").start();
process.waitFor();
Analyzer analyzer_is = new Analyzer(process.getInputStream());
Analyzer analyzer_es = new Analyzer(process.getErrorStream());
analyzer_is.start();
analyzer_es.start();
analyzer_is.join();
analyzer_es.join();
System.out.println("Exit Code: " + process.exitValue());
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.example.parser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Analyzer extends Thread {
InputStream is = null;
public Analyzer(InputStream is) {
this.is = is;
}
#Override
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(this.is));
String line = "";
while((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
As suggested by the following article: http://www.javaworld.com/jw-12-2000/jw-1229-traps.html
I was able to solve the issue by launching a shell with the -c flag. The following code does what I had originally intended:
package com.example.parser;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
try {
List<String> commands = new ArrayList<String>();
commands.add("/bin/sh");
commands.add("-c");
commands.add("grep -rni --include \"*.java\" \"public static void main(\" /home/user/dev/java/Parser/parser");
Process process = new ProcessBuilder(commands).start();
Analyzer analyzer_is = new Analyzer(process.getInputStream());
Analyzer analyzer_es = new Analyzer(process.getErrorStream());
analyzer_is.start();
analyzer_es.start();
process.waitFor();
analyzer_is.join();
analyzer_es.join();
System.out.println("Exit Code: " + process.exitValue());
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.example.parser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Analyzer extends Thread {
InputStream is = null;
public Analyzer(InputStream is) {
this.is = is;
}
#Override
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(this.is));
String line = "";
while((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is probably because you don't wait for the grep to finish.
Use the waitFor method :
Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/").start();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
process.waitFor();
String line = "";
while((line = br.readLine()) != null) {
System.out.println(line);
}
Note that you may also read the output (mainly to get what happens) while it is being processed using
Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", String line;
while (true) {
line = reader.readLine(); // add IO exception catching
if (line != null) {
System.out.println(line);
} else {
Thread.sleep(DELAY); // DELAY could be 100 (ms) for example
}
}
I suppose you're sure a grep launched by the owner of the java program is more than one line long ?
The other reason could be your process is still running but your Java program just exited.
Use the process.waitFor(); and Read your input stream in a thread.
Start the process.
Lunch a thread with the process input stream as the input.
Now wait for the process to exit by using process.waitFor();
This might help!
Have a look at this project for grep in java https://code.google.com/p/grep4j
I am trying to call a simple program test.exe which is as simple as-
int main()
{
int a;
cout<<"Welcome\n";
while(cin>>a&&a!=0)
cout<<"you entered "<<a<<endl;
}
I want to run it from a java program as a process, and send+recieve i/o from it. I am using the process with 2 threads as follows-
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Processproblem {
public static void main(String[] args)throws IOException, InterruptedException {
final Process process;
try {
process = Runtime.getRuntime().exec("test.exe");
} catch (IOException e1) {
e1.printStackTrace();
return;
}
new Thread(new Runnable() {
public void run() {
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
try {
while ((line = br.readLine()) != null) {
System.out.println("[OUT] " + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
byte[] buffer = new byte[1024];
int reading=0;
System.out.println(reading);
BufferedWriter bw= new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
while(reading!=-1)
{
reading= System.in.read(buffer);
for(int i = 0; i < buffer.length; i++) {
int intValue = new Byte(buffer[i]).intValue();
if (intValue == 0) {
reading = i;
break;
}
else
{
bw.append((char)intValue);
}
}
bw.newLine();
bw.flush();
}
} catch (Exception e) {
}
}
}
).start();
}
}
But they are not working as expected. When i run the program it just shows the "Welcome\n" message and then stops for input. When i give a integer and press enter in the java console it does nothing.
What am I doing wrong? They are two separate threads so why are they blocking each other? Is there any problem in my concept?
The program waits for your input. Grab the process output stream (using getOutputStream) and write to it.