I am just trying to control processbuilder inputstream and outputstream from different class
It is main class
public class Controller
{
public static void main(String[]args)
{
Runner r=new Runner("Test");
r.activateInput();
r.setInput("Test");
}
}
It is other class to run process
import java.io.*;
public class Runner
{
boolean activeInput=true;
boolean active=true;
String input;
public Runner(String command)
{
try {
// create a new process
System.out.println("Creating Process...");
ProcessBuilder compile = new ProcessBuilder("java","TestOut");
compile.directory(new File("C:/Users/abhishek221192/Documents/Socket"));
Process process = compile.start();
OutputStream stdin = process.getOutputStream ();
InputStream stderr = process.getErrorStream ();
InputStream stdout = process.getInputStream ();
final BufferedReader reader = new BufferedReader (new InputStreamReader(stdout));
BufferedReader error = new BufferedReader (new InputStreamReader(stderr));
final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
//final Scanner scan=new Scanner(System.in);
Thread T=new Thread(new Runnable() {
@Override
public void run() {
while(active)
{
if(activeInput)
System.out.println(activeInput+" "+input);
String data ="Abhi";
data += "\n";
try {
if(activeInput){
writer.write(data);
writer.flush();
activeInput=false;
}
//
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} );
T.start();
T.setName("Input");
Thread T1=new Thread(new Runnable() {
@Override
public void run() {
String line;
try{
while ((line = reader.readLine ()) != null) {
System.out.println(line);
}} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} );
T1.start();
T1.setName("Output");
/*
String line;
while ((line = error.readLine ()) != null) {
System.out.println(line);
}
*/
//stdout.close();
//error.close();
//T.stop();
//stdin.close();
//System.err.println("stdin closed");
active=false;
// close the output stream
System.out.println("Closing the output stream...");
//testProcessBuilder();
} catch (Exception ex) {
System.out.println("Error"+ex.getMessage());
}
}
public void activateInput()
{
this.activeInput=true;
System.out.println("active"+activeInput);
}
public void setInput(String input)
{
this.input=input;
}
}
It is TestOut code it include only one input statement
TestOut.java
import java.util.*;
public class TestOut
{
public static void main(String[]args)
{
Scanner sc=new Scanner(System.in);
System.out.println("Output hello TestOut");
System.out.println("Output1 "+sc.nextLine());
}
}
I am geting this output
Creating Process...
true null
Closing the output stream...
activetrue
Output hello TestOut
Output1 Abhi
r.setInput();
is not setting value
Couple of changes i made to make it work. the main problem with this piece of code is concurrency issues as two threads are working on same set of data. activeInput is being modified by Controller
and by thread T
Change 1:
public synchronized void activateInput(boolean activate) {
this.activeInput = activate;
System.out.println("active" + activeInput);
}
if (activeInput) {
writer.write(data);
writer.flush();
activateInput(false);
}
declared method activateInput
synchronized
and replaced activateInput = false
with the method call in thread T
Change 2:
// active = false;
commented out this line at the end of Runner()
method because it is stopping the writer Thread unnecessarily.
Change 3:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Added this at the end of Writer Thread's while loop to give writer Thread T some breathing space and to give it a chance on reading the values.
Output: Here is the output i got:
Creating Process...
activetrue
Output hello TestOut
true Test
activefalse
Output1 Abhi
Hope this helps.