Using Runtime.getRuntime().exec in eclipse

2019-04-13 05:56发布

问题:

I'm using Runtime.getRuntime().exec in eclipse to run another java program from the current program. I've used the following code.

InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
System.out.println("Enter the class name");
String s=br.readLine();    
String str="XYZ";
String[] cmd = {"java","-cp", "C:/Users/..../workspace/Testing/bin",s,str};         
Process pro=Runtime.getRuntime().exec(cmd);

I'm also passing a string "XYZ" to that program. That program just accepts the string and displays

Your string is XYZ

But by using the line

String[] cmd = {"java","-cp", "C:/Users/..../workspace/Testing/bin",s,str};

i'm able to run the program but it is not accepting any arguments. It is neither displaying the output nor showing any errors.

Where am i going wrong?

Consider the program to be called is

import java.io.*;
public class Test
{
public static void main(String[] args) throws IOException
{   
    InputStreamReader isr=new InputStreamReader(System.in);
    BufferedReader br=new BufferedReader(isr);
    System.out.println("Enter any string");
    String s=br.readLine();
    System.out.println("Your string is "+s);    
}
}

This program should accept the string XYZ and prints Your string is XYZ

回答1:

You need to read the output (and error) streams from the Process using getInputStream() and getErrorStream(). You’ll need a separate thread for this if you want to wait for the process to complete.

String[] cmd = {"java", "-cp", "C:/Users/..../workspace/Testing/bin", s, str};
Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();
final InputStream pOut = p.getInputStream();
Thread outputDrainer = new Thread()
{
    public void run()
    {
        try
        {
            int c;
            do
            {
                c = pOut.read();
                if (c >= 0)
                    System.out.print((char)c);
            }
            while (c >= 0);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
};
outputDrainer.start();

p.waitFor();

If you are using Java 7 and want all output of the process to be redirected to the console, the code is considerably simpler:

String[] cmd = {"java", "-cp", "C:/Users/..../workspace/Testing/bin", s, str};
Process p = new ProcessBuilder(cmd).redirectError(Redirect.INHERIT)
                                   .redirectOutput(Redirect.INHERIT)
                                   .start();
p.waitFor();

The redirectError() and redirectOutput() methods with Redirect.INHERIT cause output to just be sent to the parent Java process.



回答2:

You are executing javac, the language compiler. I believe you want to invoke the java runtime on the class file with your main method. Replace javac with java, and specify your main class.



回答3:

You are passing your data as an Argument but reading it from System.in. If you read the data from the arguments it'll work. So do what @prunge said to capture what the subprocess print and use this as your test and everything will work just fine.

import java.io.*;
public class Test
{
    public static void main(String[] args) throws IOException
    {   
        if(args.length==0)
            System.out.println("No String received");
        else
            System.out.println("Your string is " + args[0]);    
    }
}

Be sure that you check both the InputStream and the ErrorStream.

If you however want to pass the data via System.in then you have to change your call code to:

InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
System.out.println("Enter the class name");
String s=br.readLine();    
String str="XYZ";
String[] cmd = {"java","-cp", "C:/Users/..../workspace/Testing/bin",s};         
Process pro=Runtime.getRuntime().exec(cmd);
PrintWriter output= new PrintWriter(pro.getOutputStream());
output.println(str);