2

Here's the situation. Im creating a UI which will allow make using a genetic programming system (ECJ) easier to use.

Currently you need to run a command prompt within the ECJ folder and use the commands similar to this to execute a parameter file.

java ec.Evolve -file ec\app\tutorial5\tutorial5.params

Where the full path of tutorial5 is

C:\Users\Eric\Documents\COSC\ecj\ec\app\tutorial5\tutorial5.params

and the command prompt must be executed from

C:\Users\Eric\Documents\COSC\ecj

My program makes the user select a .params file (which is located in a ecj subdirectory) and then use the Runtime.exec() to execute

java ec.Evolve -file ec\app\tutorial5\tutorial5.params

What i have so far

// Command to be executed
String cmd = "cd " + ecjDirectory;        
String cmd2 = "java ec.Evolve -file " + executeDirectory;


System.out.println(cmd);
try {
    Process p = Runtime.getRuntime().exec(
                new String[]{"cmd.exe", "/c", cmd, cmd2});
    BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
    statusTF.append(r.readLine());
    p.waitFor();        

    } catch (IOException | InterruptedException ex) {
        System.out.println("FAILED: " + ex.getMessage());
        statusTF.append("Failed\n");
    }

Currently it outputs the change directory command but nothing else. Can this be done?

George
  • 337
  • 2
  • 7
  • 16

3 Answers3

1

First, the 'cd' command can't be executed by Runtime.exec() in the first place (see How to use "cd" command using Java runtime?). You should be able to just set the working directory for the process when you call exec (see below).

Second, running 'cmd.exe /c' to execute your process isn't what you want here. You won't be able to get the results of your process running, because that is returned to the command window -- which eats the error and then closes without passing the error along to you.

Your exec command should look more like this:

Process p = Runtime.getRuntime().exec(
    command, null, "C:\Users\Eric\Documents\COSC\ecj");

Where 'command' looks like this:

String command = "java ec.Evolve -file ec\app\tutorial5\tutorial5.params"

Edit: For reading error messages, try this:

String error = "";
try (InputStream is = proc.getErrorStream()) {
    error = IOUtils.toString(is, "UTF-8");
}
int exit = proc.waitFor();
if (exit != 0) {
    System.out.println(error);
} else {
    System.out.println("Success!");
}
Community
  • 1
  • 1
Dave
  • 363
  • 2
  • 9
  • I have changed this as i was getting an error passing a string value for the directory. Process p = Runtime.getRuntime().exec(cmd2, null, new File(ecjDirectory)); It works, but i have no way of knowing when it finishes executing, and sometimes the results from what ive called does not finish the executions until i terminate the program. – George Apr 16 '15 at 00:41
  • error = IOUtils.toString(is, "UTF-8"); is giving me errors. The exit isnt occuring as i dont think the file im running provides an exit code. The application locks up and until i close the program the final results of the commands i ran dont finish and show their results. – George Apr 16 '15 at 03:33
  • Ok, try one more thing... make this call directly after Runtime.getRuntime().exec(): proc.getOutputStream().close(); – Dave Apr 16 '15 at 14:05
  • proc.getOutputStream().close() ensures that the process isn't sitting there waiting to see if there is more user input -- it's possible that's what's happening here. – Dave Apr 16 '15 at 14:06
0

You can use Java processbuilder: processBuilder documentation!
you can define the working directory of the process and all other stuff.

igreenfield
  • 1,618
  • 19
  • 36
0

Each call to exec() runs in a new environment, this means that the call to cd will work, but will not exist to the next call to exec().

I prefer to use Apache's Commons Exec, it's provides an excellent facade over Java's Runtime.exec() and gives a nice way to specify the working directory. Another very nice thing is they provide utilities to capture standard out and standard err. These can be difficult to properly capture yourself.

Here's a template I use. Note that this sample expects an exit code of 0, your application may be different.

String sJavaPath = "full\path\to\java\executable";
String sTutorialPath = "C:\Users\Eric\Documents\COSC\ecj\ec\app\tutorial5\tutorial5.params";
String sWorkingDir = "C:\Users\Eric\Documents\COSC\ecj";

try (
        OutputStream out = new ByteArrayOutputStream();
        OutputStream err = new ByteArrayOutputStream();
    )
{
    // setup watchdog and stream handler
    ExecuteWatchdog watchdog = new ExecuteWatchdog(Config.TEN_SECONDS);
    PumpStreamHandler streamHandler = new PumpStreamHandler(out, err);

    // build the command line
    CommandLine cmdLine = new CommandLine(sJavaPath);
    cmdLine.addArgument("ec.Evolve");
    cmdLine.addArgument("-file");
    cmdLine.addArgument(sTutorialPath);

    // create the executor and setup the working directory
    Executor exec = new DefaultExecutor();
    exec.setExitValue(0); // tells Executor we expect a 0 for success
    exec.setWatchdog(watchdog);
    exec.setStreamHandler(streamHandler);
    exec.setWorkingDirectory(sWorkingDir);

    // run it
    int iExitValue = exec.execute(cmdLine);

    String sOutput = out.toString();
    String sErrOutput = err.toString();
    if (iExitValue == 0)
    {
        // successful execution
    }
    else
    {
        // exit code was not 0
        // report the unexpected results...
    }
}
catch (IOException ex)
{
    // report the exception...
}
MCToon
  • 638
  • 5
  • 10
  • Hello ... Can you give us the java code where you have used this template to execute a java application and print it's output on the console? – Vinit Gaikwad Oct 27 '15 at 07:26