42

Hello i have some question about java. here is my code:

public static void main(String[] args) throws Exception {
    Process pr = Runtime.getRuntime().exec("java -version");

    BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
    String line;
    while ((line = in.readLine()) != null) {
        System.out.println(line);
    }
    pr.waitFor();
    System.out.println("ok!");

    in.close();
    System.exit(0);
}

in that code i'am trying to get a java version command execute is ok, but i can't read the output it just return null. Why?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
maxormo
  • 599
  • 1
  • 4
  • 10

5 Answers5

68

Use getErrorStream().

BufferedReader in = new BufferedReader(new InputStreamReader(pr.getErrorStream()));

EDIT:

You can use ProcessBuilder (and also read the documentation)

ProcessBuilder   ps=new ProcessBuilder("java.exe","-version");

//From the DOC:  Initially, this property is false, meaning that the 
//standard output and error output of a subprocess are sent to two 
//separate streams
ps.redirectErrorStream(true);

Process pr = ps.start();  

BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
    System.out.println(line);
}
pr.waitFor();
System.out.println("ok!");

in.close();
System.exit(0);
Clashsoft
  • 11,553
  • 5
  • 40
  • 79
KV Prajapati
  • 93,659
  • 19
  • 148
  • 186
  • 2
    ok, it is work. but strange read normal output of command from error stream. – maxormo Nov 16 '11 at 10:27
  • @max - Take a look at - http://download.oracle.com/javase/1.5.0/docs/api/java/lang/ProcessBuilder.html – KV Prajapati Nov 16 '11 at 10:31
  • @AVD there described how to merge error & standard outputs. but not describe why it marked as 'error'. It's really seems strange. – Alexiuscrow Dec 22 '16 at 12:09
  • @adatapost what is the approach if I am using `Process.waitFor()` in conjunction with reading this stream? e.g. a download is occurring. Will the `line` have to complete printing, then I can hit my logic to forcibly destroy process (e.g. `pr.destory()`) I want to know if they can execute in parallel. – Kervvv Apr 29 '18 at 22:25
  • If you are doing something liek: `new ProcessBuilder().command().inheritIO()` remove the `inheritIO()` or the stream will get redirected to console and not to `in` – absin Jul 02 '18 at 10:09
11

Note that we're reading the process output line by line into our StringBuilder. Due to the try-with-resources statement we don't need to close the stream manually. The ProcessBuilder class let's us submit the program name and the number of arguments to its constructor.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ProcessOutputExample
{
    public static void main(String[] arguments) throws IOException,
            InterruptedException
    {
        System.out.println(getProcessOutput());
    }

    public static String getProcessOutput() throws IOException, InterruptedException
    {
        ProcessBuilder processBuilder = new ProcessBuilder("java",
                "-version");

        processBuilder.redirectErrorStream(true);

        Process process = processBuilder.start();
        StringBuilder processOutput = new StringBuilder();

        try (BufferedReader processOutputReader = new BufferedReader(
                new InputStreamReader(process.getInputStream()));)
        {
            String readLine;

            while ((readLine = processOutputReader.readLine()) != null)
            {
                processOutput.append(readLine + System.lineSeparator());
            }

            process.waitFor();
        }

        return processOutput.toString().trim();
    }
}

Prints:

java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
turbanoff
  • 2,439
  • 6
  • 42
  • 99
BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185
2

You already have the process-object (name pr). You can get the Input-, Output- and Errorstream. In your case you want pr.getInputStream(). Read from that, that is connected to the output of the process.

Mnementh
  • 50,487
  • 48
  • 148
  • 202
0

try this

public static final Pair<Integer,Integer> javaVersion(File file) throws IOException {
    final ProcessBuilder pb = new ProcessBuilder("java", "-version");
    pb.directory(new File(file.getCanonicalPath() + File.separator  + "bin"));
    pb.redirectErrorStream(true);

    // Call the test target
    final Process process = pb.start();
    final InputStream in = process.getInputStream();
    final InputStream err = process.getErrorStream();

    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in,"UTF-8"));
    String s = bufferedReader.readLine();
    int start = s.indexOf('\"');
    int end = s.lastIndexOf('\"');
    String substring = s.substring(start + 1, end);
    String[] split = substring.split("\\.");

    return new Pair<>(Integer.parseInt(split[0]),Integer.parseInt(split[1]));
}
IvanRF
  • 7,115
  • 5
  • 47
  • 71
Kadir BASOL
  • 729
  • 2
  • 10
  • 20
0

I also suffered this issue because I didn't set $JAVA_HOME correctly. (I forgot Contents/Home).
After I edit $JAVA_HOME, update Gradle JVM, and remove .idea directory to re-build with gradle, It works well.

Kideok Kim
  • 185
  • 1
  • 10