2015-04-15 59 views
2

這就是情況。我創建了一個UI,這將允許使用遺傳編程系統(ECJ)更容易使用。Java Runtime.exec()運行一個java程序

當前您需要在ECJ文件夾內運行命令提示符,並使用與此類似的命令來執行參數文件。

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

凡tutorial5的完整路徑是

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

和命令提示必須從

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

我的程序使用戶選擇一個.params文件(它位於要執行在ecj子目錄中),然後使用Runtime.exec()執行

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

我有什麼到目前爲止

// 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"); 
    } 

目前,它輸出的更改目錄命令,但沒有別的。 可以這樣做嗎?

+0

程序是否完成時出現錯誤或只是掛起exec()命令之後? – Dave

+0

try語句無錯誤地結束 – George

回答

1

首先,'cd'命令不能由Runtime.exec()首先執行(請參閱How to use "cd" command using Java runtime?)。當你調用exec時,你應該能夠設置進程的工作目錄(見下文)。

其次,運行'cmd.exe/c'來執行你的進程並不是你想要的。您將無法獲取正在運行的進程的結果,因爲該結果會返回到命令窗口 - 它會消除錯誤,然後關閉而不會將錯誤傳遞給您。

你exec命令應該看上去就像這樣:

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

其中 '命令' 看起來是這樣的:

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

編輯:讀取故障信息,試試這個:

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!"); 
} 
+0

我改變了這個,因爲我得到了一個傳遞目錄字符串值的錯誤。進程p = Runtime.getRuntime()。exec(cmd2,null,new File(ecjDirectory));它可以工作,但是我無法知道它何時執行完畢,有時候我所調用的結果在我終止程序之前並未完成執行。 – George

+0

進行編輯以顯示如何閱讀錯誤消息。 – Dave

+0

error = IOUtils.toString(is,「UTF-8」);給我錯誤。出口沒有發生,因爲我不認爲文件即時運行提供退出代碼。該應用程序鎖定,直到我關閉程序我運行的命令的最終結果不完成並顯示其結果。 – George

0

每次撥打exec()都會在新的環境中運行,這意味着撥打cd將工作,但不會存在到exec()的下一個電話。

我更喜歡使用Apache's Commons Exec,它爲Java的Runtime.exec()提供了一個很好的外觀,並提供了一個很好的方式來指定工作目錄。另一個非常好的事情是他們提供實用程序來捕獲標準輸出和標準錯誤。這些可能很難適當地捕捉自己。

這是我使用的模板。請注意,此示例預計退出代碼爲0,您的應用程序可能會有所不同。

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... 
} 
+0

你好...你可以給我們java代碼,你已經使用這個模板來執行一個Java應用程序,並在控制檯上輸出它的輸出嗎? –