Running system commands in Java applications

UPDATE: This article has been replaced by my newer "Java exec with ProcessBuilder and Process" article. While the Java code shown in this tutorial works on simple "Java exec" cases, the new article shows how to properly read the output streams from your system command in Java threads, and also how to write to your command's standard input, if necessary.

Feel free to read this article for background/legacy information, but I strongly recommend that you use the source code I'm sharing in my newer "Java exec" article, because it resolves the standard input, output, and error problems that I didn't handle properly in the code below.

Introduction

I've read a lot about Java but one of the things I rarely see discussed is how you should go about running external system commands. Of course, you probably don't read much about this because it takes away from the portability of Java applications. For instance, if you write a Java application on a Unix system, you might be interested in running the "ps -ef" command, and reading the output of the command. For Unix systems this is great, but unfortunately, this same program won't work on a Windows system because the ps command isn't available on Windows.

Well, we're going to forget about portability for this article, and demonstrate a method that can be used to run system commands. We've received a lot of requests about this topic, so here goes.

Discussion (Runtime exec and Process)

Executing a system command is relatively simple - once you've seen it done the first time. It involves the use of two Java classes, the Runtime class and the Process class. Basically, you use the exec method of the Runtime class to run the command as a separate process. Invoking the exec method returns a Process object for managing the subprocess. Then you use the getInputStream() and getErrorStream() methods of the Process object to read the normal output of the command, and the error output of the command. What you do with the output of the command executed is entirely up to you and the application you're creating.

(Note: There is also a getOutputStream() method that you can use to write to the process, but we won't cover that method in this article. We'll cover that and a few other advanced features in a future article.)

A Java exec example

The code shown in Listing 1 provides a working example of our "Java exec" technique in a file named JavaRunCommand.java.

import java.io.*;

public class JavaRunCommand {

    public static void main(String args[]) {

        String s = null;

        try {
            
	    // run the Unix "ps -ef" command
            // using the Runtime exec method:
            Process p = Runtime.getRuntime().exec("ps -ef");
            
            BufferedReader stdInput = new BufferedReader(new 
                 InputStreamReader(p.getInputStream()));

            BufferedReader stdError = new BufferedReader(new 
                 InputStreamReader(p.getErrorStream()));

            // read the output from the command
            System.out.println("Here is the standard output of the command:\n");
            while ((s = stdInput.readLine()) != null) {
                System.out.println(s);
            }
            
            // read any errors from the attempted command
            System.out.println("Here is the standard error of the command (if any):\n");
            while ((s = stdError.readLine()) != null) {
                System.out.println(s);
            }
            
            System.exit(0);
        }
        catch (IOException e) {
            System.out.println("exception happened - here's what I know: ");
            e.printStackTrace();
            System.exit(-1);
        }
    }
}

Listing 1 (above): The file JavaRunCommand.java shows how you can run an external system command from within a Java program.

How our Java exec code works

The first thing you do is specify the command you want to run by supplying this command to the Runtime class. Because you can't create your own instance of the Runtime class, you first use the getRuntime method to access the current runtime environment and then invoke the Runtime exec method. This returns a Process object.

Everything else you do involves methods of the Process object. In this case, because we're running the "ps -ef" command on a Unix system, we just need to read the output of the command. Reading the standard error probably isn't required in this case, but I thought at the very least it was at least worth showing, if not good programming practice.

I convert the input streams with the InputStreamReader and BufferedReader so I can use the readLine() method of the BufferedReader class. Because I use these classes, this application will not compile properly with an older JDK 1.0.x compiler (these classes weren't available in 1.0.x).

Download the "Java exec" example source code

I could go on at length about this topic, but the best thing I can recommend is that you download the source code and work with it for a while. Try running different commands to see if you can get them to work properly, and try to run a command that requires input (this will be a bit more complicated).

To download the JavaRunCommand.java source code shown in Listing 1, click here. Once the file is displayed in your browser you can select the File | Save As ... option of your browser to save the code to your local filesystem.

Permalink

Hi
Is it possible to run the same command on a remote machine?
I am currently able to run it only on my local machine. Can I give the login details and IP address of a different machine and execute a system command remotely?

Thanks

Regards
Ananth

Hi, my name is sumit vadgama.i am T.Y.B.C.A. Student.i have problem when i type java comand in cmd , the option -hotspot not worked and also not under stand the mean of that.have any one to idea about this? Pls help me for this.

Permalink

hello alvin,
thanks for such really nice article, it helps me a lot.

I have one query,,,,

Suppose i want to execute 'ls' command for a specific directory on linux.
When i use above code (with replacing command to 'ls') to display list. It displays the files & folders within current directory from where i had executed the code....

But I want to execute 'ls' for another directory which may be in the same directory hierarchy or in different...

What should I add to code above , to accomplish this...

Thank you
Suyog

Permalink

Hello Alvin,
Thanks for your reply..

I am trying to clear my doubts here as :

Suppose I am in the directory /home/Abc/xyz/pqr.
Now if I execute command Runtime.getRuntime().exec("ls");
it displays files & folders inside 'pqr'.

But I want listing from /home/Abc , without giving absolute path..
So, do I need to execute 'cd' command which will get you to the home directory & then directly execute above 'ls' command to list all files & folders inside home directory .. ???

(I tried above , but not working & giving error as
Cannot run program "cd": java.io.IOException: error=2, No such file or directory)

Permalink

Hello Alvin,
Thank you very much for your response. I am studying this material/topic, & if I found any potential information then i ll definitely post here...

Thanks & Regards
Suyog

Hello Alvin,

Wonderful post I believe. Thanks for sharing your experience on this.

I have one query as of now:-

how can I execute the query on remote machine? I have seen few other posts from you, but in one of the posts you have written a Ruby Script for achieving few things, since Ruby Script is not available for any Unix based machines, I just wanted to know how I can do a telnet session to a Unix machine and execute the commands remotely from my application running on Windows machine.

Regards,
Ravi

Permalink

Hi,

I want run my perl file which is present in unix box from my jsp code so I have written like
Process process=Runtime.getRuntime().exec("./sso_example.pl");

but I am not able run this ,any help pls?

Permalink

Thank you very much Alvin your comment about piping with java exec just saved my life, if there is a God I'm sure he will reward you with beautiful women and lots of money. Thanks again!!

Permalink

This is a very helpful post. Thank you for sharing.

Permalink

Hi everyone.
Well, I'm trying to run JAR command for creating Java ARchive from Java code.
So, I already done to generate classes from WSDL and compile them successfully, but now i have some trouble. I can not run JAR command. Because, before calling JAR, I have to run "cd C:\temp\" and then "jar cf client.jar @classes.list".
Two commands! So... Please, who can give an advise here? I really need help!

I'm sorry, I don't have a Windows system these days, so I can't try to test anything. Before I learned how to do all of this, I used to call a shell script on Unix and Linux systems whenever I needed to run multiple commands, so maybe you can do the same thing on a Windows system, and call a Windows batch file to run your commands?

Permalink

Its 11 o'clock p.m. on Christmas. I haven't slept in two days and have been trying to work on a program like this for a while now. Thanks to you I figured out what I needed for it to run properly. If it wasn't for you I would still need to stay up and finish this.

Thank you and God Bless

Permalink

To try out this command I tried a ls command with wildcard *
But I could not get it to work.
A simple "ls /home/martin" works fine, but not "ls /home/martin/*.java"

A quick note here that I've created a new tutorial on how to execute system commands from Java using ProcessBuilder and Process. That article not only uses these newer Java classes, but it also resolves the issues of reading the standard output and standard error streams from the system command you want to execute.
I strongly recommend that you use the code from that article, as opposed to the code in this article, in particular because it handles the output and error streams properly.

Permalink

wildcard works with bash

String[] cmd = { "/bin/bash", "-c", "cd /var; ls *.java" };
Process p = Runtime.getRuntime().exec(cmd);

Permalink

I'm trying to use the method signature below to set a long classpath for executing a separate java application from within my own. It seems like the classpath is failing to be set any ideas?
exec(String[] cmdarray, String[] envp)

used:
exec("(fully qualified)/java (classname) -args", environment);

where environment = {"CLASSPATH=(classpath)"} and a few other environment variables.

any ideas would be much appreciated.

Permalink

i want to use a program of java which run commands of shell. i have tried with the suggestions have given above but i doen't worck with all the commands???? "as: sudo virsh, ?????"
so thinks for the answer!!!!

For an example like that, where you want to exec the sudo command, you're going to need to properly work with the input and output streams. To do that, you'll have to use my newer (and more complicated code), as shown in my "Java exec with Process and ProcessBuilder" article. I specifically created that project so I could run the sudo command from a Java exec method call.

I don't know if the Apache exec project handles something like the sudo command, but you may want to look at it as well.

Permalink

Hi,I am running exec on window. I am trying to open the cmd and input the command. The code worked. I also try to type: cd .. or dir for testing it worked too.
However I was trying to input a command ( business sentitive, I cannot postup) . This command work when I manually type in cmd. However when using code to execute, the windows freeze ? I looked like as it is waiting for something. Any idea to why this is happening or way to resolve this ?

Thanks

Permalink

hi , i am trying to access the network drive using runtime exec(),

but i am getting IO Exception .

here is the part of code :
------------------------------cut from code-----------------------------
commands= new String[] {"cmd /c C:\\APP\\Adl2\\bin\\runpx.cmd http://2IND05724.LED.XYZ.com:7779/ServerService \"\\\\abcd\\mysig\\file.zip\" -monitor"};
Process p = Runtime.getRuntime().exec(commands);

------------------------------- end of cut--------------------------------

in the above code "\\abce is common network drive

can any one help with this ..

Add new comment

The content of this field is kept private and will not be shown publicly.

Anonymous format

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul type> <ol start type> <li> <pre>
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.