140

Is there a way to run this command line within a Java application?

java -jar map.jar time.rel test.txt debug

I can run it with command but I couldn't do it within Java.

M. A. Kishawy
  • 5,001
  • 11
  • 47
  • 72
Ataman
  • 2,530
  • 3
  • 22
  • 34

8 Answers8

213
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("java -jar map.jar time.rel test.txt debug");

http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html

kol
  • 27,881
  • 12
  • 83
  • 120
  • is it normal that when i try to output it to console it only outputs something like this: java.lang.ProcessImpl@6ecec5288 – Ataman Dec 13 '11 at 21:40
  • 8
    Use `pr.getInputStream()`. Here is a detailed example: http://www.linglom.com/2007/06/06/how-to-run-command-line-or-execute-external-application-from-java/ – kol Dec 13 '11 at 21:43
  • 6
    It's useful to check what the process returns with. You can get that with pr.waitFor(). So it looks like this: `int retVal = pr.waitFor()`. So if it's not 0, you can abort / clean up. – Apache Dec 10 '13 at 15:32
  • 1
    Is there a practical/meaningful difference between `pr.exitValue` and `pr.waitFor()`? Update: I think exitValue will throw an exception if the process has not finished where as waitFor... you know – Don Cheadle Dec 11 '14 at 20:04
  • 3
    nothing it's more java than "Runtime rt = Runtime.getRuntime();" – Andrea Bori Jun 21 '16 at 10:30
  • This answer is problematic. The called app will block unless you read BOTH stderr and stdout. You will get away with it if only a small amount of output is written but once the buffer is exceeded everything stops. – Brett Sutton Jul 06 '23 at 03:20
60

You can also watch the output like this:

final Process p = Runtime.getRuntime().exec("java -jar map.jar time.rel test.txt debug");

new Thread(new Runnable() {
    public void run() {
        BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line = null;

        try {
            while ((line = input.readLine()) != null)
                System.out.println(line);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();

p.waitFor();

And don't forget, if you are running a windows command, you need to put cmd /c in front of your command.

EDIT: And for bonus points, you can also use ProcessBuilder to pass input to a program:

String[] command = new String[] {
        "choice",
        "/C",
        "YN",
        "/M",
        "\"Press Y if you're cool\""
};
String inputLine = "Y";

ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));

writer.write(inputLine);
writer.newLine();
writer.close();

String line;

while ((line = reader.readLine()) != null) {
    System.out.println(line);
}

This will run the windows command choice /C YN /M "Press Y if you're cool" and respond with a Y. So, the output will be:

Press Y if you're cool [Y,N]?Y
Craigo
  • 3,384
  • 30
  • 22
  • 5
    You can also use p.getErrorStream to understand why your command is broken! – jakebeal Jan 29 '15 at 04:27
  • 1
    @Craigo: any reference regarding your "cmd /c" statement? thx – Campa Dec 15 '15 at 08:44
  • 2
    Actually, I think you only need the "cmd /c", if you are wanting to run a windows command, like "copy". Apologies for the confusion. – Craigo Dec 15 '15 at 23:56
  • 1
    this doesn't print the whole output for me. executing "ls" prints different amounts of the directory contents each time. this works best for me: http://alvinalexander.com/java/edu/pj/pj010016 – stuart Feb 24 '17 at 02:54
22

To avoid the called process to be blocked if it outputs a lot of data on the standard output and/or error, you have to use the solution provided by Craigo. Note also that ProcessBuilder is better than Runtime.getRuntime().exec(). This is for a couple of reasons: it tokenizes better the arguments, and it also takes care of the error standard output (check also here).

ProcessBuilder builder = new ProcessBuilder("cmd", "arg1", ...);
builder.redirectErrorStream(true);
final Process process = builder.start();

// Watch the process
watch(process);

I use a new function "watch" to gather this data in a new thread. This thread will finish in the calling process when the called process ends.

private static void watch(final Process process) {
    new Thread() {
        public void run() {
            BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = null; 
            try {
                while ((line = input.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }.start();
}
Community
  • 1
  • 1
mountrix
  • 1,126
  • 15
  • 32
8
Runtime.getRuntime().exec("java -jar map.jar time.rel test.txt debug");
Igor Popov
  • 9,795
  • 7
  • 55
  • 68
8
import java.io.*;

Process p = Runtime.getRuntime().exec("java -jar map.jar time.rel test.txt debug");

Consider the following if you run into any further problems, but I'm guessing that the above will work for you:

Problems with Runtime.exec()

Shaun
  • 2,446
  • 19
  • 33
4

what about

public class CmdExec {

public static Scanner s = null;


public static void main(String[] args) throws InterruptedException, IOException {
    s = new Scanner(System.in);
    System.out.print("$ ");
    String cmd = s.nextLine();
    final Process p = Runtime.getRuntime().exec(cmd);

    new Thread(new Runnable() {
        public void run() {
            BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line = null; 

            try {
                while ((line = input.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();

    p.waitFor();
     }

 }
Denis
  • 390
  • 3
  • 14
3
Process p = Runtime.getRuntime().exec("java -jar map.jar time.rel test.txt debug");
rink.attendant.6
  • 44,500
  • 61
  • 101
  • 156
Wojciech Owczarczyk
  • 5,595
  • 2
  • 33
  • 55
3

Have you tried the exec command within the Runtime class?

Runtime.getRuntime().exec("java -jar map.jar time.rel test.txt debug")

Runtime - Java Documentation

rybosome
  • 5,046
  • 7
  • 44
  • 64