Saturday 17 November 2012

Running commands from java programs

There might come a situation when you will have to run OS commands from your java program. Requirement may differ but I find running, "javac" and "java" commands, common for compiling and running the java source. This sounds complicated but it's actually a very simple job. You'll have to dig a little into the System, Runtime and Process classes.

Just write the command (which is a String in java's context) in exec method of Runtime class which takes the String argument (command) and returns an object which is a child of  Process abstract class and executes the command in this new process, separately. This Process class has got four important methods which can be used to retrieve information from the process or manipulate it. exitValue() returns int 0 on successful execution, getInputStream() is used to read the successful output from the process, getErrorStream() is used to read the output for unsuccessful execution (exitValue() will not return 0) and finally waitFor() is used to halt the parent process (main thread) till this process finishes its execution.  You may check the documentation of these classes for in depth analysis. Here, I'm going to provide a basic java program of compiling and running a java source code saved in a file dynamically from another java program.

Make a file "Source.java" and save the following code in it.
class Source{
public static void main(String... args){
 System.out.println("hello world");
}
}

Now, We are going to compile and run this class from our java program. Create a Compiler.java file in the same directory and save this code in it.


import static java.lang.System.out;
import java.io.*;
import java.util.*;

public class Compiler{

    public static void main(String... args){
        if(compileSource()){
            runSource();
        }
    }
    
    static boolean compileSource(){
        boolean status=false;
        try{
            Process p=Runtime.getRuntime().exec("javac Source.java");
            p.waitFor();
            InputStream in=p.getInputStream();
            InputStream er=p.getErrorStream();
            
            int c;
            if(p.exitValue() == 0){
                    while((c=in.read()) != -1)
                    out.print((char)c);
                    status = true;
                }
                else{
                    while((c=er.read()) != -1)
                    out.print((char)c);
                    status = false;
                }
            }
            catch(Throwable e){
                e.printStackTrace();
                }
                return status;
    }
    
    static boolean runSource(){
        boolean status=false;
        try{
            Process p=Runtime.getRuntime().exec("java Source");
            p.waitFor();
            InputStream in=p.getInputStream();
            InputStream er=p.getErrorStream();
            int c;
            if(p.exitValue() == 0){
                    while((c=in.read()) != -1)
                    out.print((char)c);
                    status=true;
                }
                else{
                    while((c=er.read()) != -1)
                    out.print((char)c);
                    status=false;
                }
            }
            catch(Throwable e){
                e.printStackTrace();
                }
                return status;
    }
}


I hope, this tutorials helps you. Feel free to comment.