1

I am starting a separate process in my Java program using ProcessBuilder This is were the process gets made:

Class klass=Program.class;
String[] output=new String[2];
 String javaHome = System.getProperty("java.home");
 String javaBin = javaHome +
         File.separator + "bin" +
         File.separator + "java";
 String classpath = System.getProperty("java.class.path");
 String className = klass.getCanonicalName();

 ProcessBuilder builder = new ProcessBuilder(
         javaBin, "-cp", classpath, className);

 Process process = builder.start();
 process.waitFor();

Program.class is the following:

public class Program {
public static void main(String[] args) {
System.out.println("Hi!");
}

I want the standard output to produce Hi!, and the standard error, if I were to, for example, not add a semicolon after System.out.println("Hi!") then the standard error would be:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
Syntax error, insert ";" to complete BlockStatements

at Program.main(Program.java:6)

So, how can I do this? Ideally, the program converts these into two strings.

Thanks

APCoding
  • 303
  • 2
  • 19
  • 1
    Take a closer look at the [`Process`](http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html), it has an `inputStream` property, which is attached to the processes stdout. You can also use `ProcessBuilder` to redirect the stderr through the stdout to make life easier – MadProgrammer Jun 24 '15 at 01:55
  • Can you use `inputStream` to add text input to the program, for example if you were using the `Scanner` class? – APCoding Jun 24 '15 at 02:00
  • No, that would be what the `outputStream` property would be for...(yes, it sounds backwards, but it actually makes sense) – MadProgrammer Jun 24 '15 at 02:02
  • So you use `outputStream` to add input to the program, and `inputStream` to get the output? What? – APCoding Jun 24 '15 at 02:03
  • Yep, try not to think about it to much. Basically, `InputStream` has "read" methods and `OutputStream` has "write" methods, you want to "read" from and "write" to – MadProgrammer Jun 24 '15 at 02:05
  • OK, so how would I implement this into my code? – APCoding Jun 24 '15 at 02:16
  • Like you would any time you try and read from an `InputStream`... – MadProgrammer Jun 24 '15 at 02:16
  • [For example](http://stackoverflow.com/questions/19968759/how-to-read-the-std-output-of-another-java-program-in-this-java-program/19969016#19969016), [example](http://stackoverflow.com/questions/18226161/running-command-prompt-in-java-program-with-gui-netbeans/18226662#18226662) and [example](http://stackoverflow.com/questions/23716144/execute-java-file-with-runtime-getruntime-exec/23716208#23716208) – MadProgrammer Jun 24 '15 at 02:19
  • OK, works perfectly, but what about adding the standard error? As of right now, if there is an error, it just does nothing – APCoding Jun 24 '15 at 02:25
  • You can use `Process#getErrorStream` and basically do the same thing as you would for the `inputStream` or use [`ProcessBuilder#redirectErrorStream(boolean)`](http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#redirectErrorStream(boolean)) – MadProgrammer Jun 24 '15 at 02:28
  • Where would I add that in my current code? The code: – APCoding Jun 24 '15 at 02:33
  • Oops, can't add that much code – APCoding Jun 24 '15 at 02:33
  • ` BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream()));` – APCoding Jun 24 '15 at 02:34
  • `String line = null;` – APCoding Jun 24 '15 at 02:34
  • `waitFor` is blocking, so until the process exists, you won't see any output. Have a lock at the last example, which uses a `Thread` to read the stream, but then blocks the calling thread by using `waitFor` – MadProgrammer Jun 24 '15 at 02:34
  • `while ((line = r.readLine()) != null) { System.out.println(line);` – APCoding Jun 24 '15 at 02:34
  • OK great, want to put all this into an answer? – APCoding Jun 24 '15 at 02:36

1 Answers1

2

Start by taking a closer look at the Process class, it has an inputStream property, which is attached to the processes stdout. You can also use ProcessBuilder to redirect the stderr through the stdout to make life easier, using ProcessBuilder#redirectErrorStream(boolean)

You can write to the Process using its outputStream property (try not to think about it to much)...

Basically, you want to "read" the "output", via the inputStream and "write" to the "input" via the outputStream

Something like...

Class klass=Program.class;
String[] output=new String[2];
String javaHome = System.getProperty("java.home");
String javaBin = javaHome +
     File.separator + "bin" +
     File.separator + "java";
String classpath = System.getProperty("java.class.path");
String className = klass.getCanonicalName();

ProcessBuilder builder = new ProcessBuilder(
     javaBin, "-cp", classpath, className);
builder.redirectErrorStream(true);

Process process = builder.start();
int in = -1;
InputStream is = process.getInputStream();
try {
    while ((in = is.read()) != -1) {
        System.out.println((char)in);
    }
} catch (IOException ex) {
    ex.printStackTrace();
}
int exitCode = process.waitFor();
System.out.println("Exited with " + exitCode);

as an example

python dude
  • 7,980
  • 11
  • 40
  • 53
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366