簡體   English   中英

Java Runtime.exec()

[英]Java Runtime.exec()

我可以從命令行運行此命令,而不會出現任何問題(執行驗證腳本):

c:/Python27/python ../feedvalidator/feedvalidator/src/demo.py https://das.dynalias.org:8080/das_core/das/2.16.840.1.113883.4.349/1012581676V377802/otherAdminData/careCoordinators 

從java,如果我離開URL參數,只是做:

String[] args1 = {"c:/Python27/python", "../feedvalidator/feedvalidator/src/demo.py" };
Runtime r = Runtime.getRuntime();
Process p = r.exec(args1);

它工作正常。 如果我使用某些URL作為參數,例如:

String[] args1 = {"c:/Python27/python", "../feedvalidator/feedvalidator/src/demo.py" , "http://www.intertwingly.net/blog/index.atom"};
// or 
String[] args1 = {"c:/Python27/python", "../feedvalidator/feedvalidator/src/demo.py" , "http://www.cnn.com"};

它也可以正常工作。

但是,如果我使用這個特定的URL https://das.dynalias.org:8080/das_core/das/2.16.840.1.113883.4.349/1012581676V377802/otherAdminData/careCoordinators ,則腳本會掛起(java等待過程完成)。 我不確定為什么它可以從該URL的命令行運行,而不是從Java程序運行。 我嘗試添加引號將URL參數括起來,但這也不起作用。 我認為URL中沒有任何需要轉義的字符。

完整代碼:

String urlToValidate = "https://das.dynalias.org:8080/das_core/das/2.16.840.1.113883.4.349/1012581676V377802/otherAdminData/careCoordinators";

String[] args1 = {"c:/Python27/python", "C:/Documents and Settings/vhaiswcaldej/DAS_Workspace/feedvalidator/feedvalidator/src/demo.py", urlToValidate };
System.out.println(args1[0] + " " + args1[1] + " " + args1[2]);

Runtime r = Runtime.getRuntime();
Process p = r.exec(args1);
BufferedReader br = new BufferedReader(new InputStreamReader(
p.getInputStream()));
int returnCode = p.waitFor();
 System.out.println("Python Script or OS Return Code: " + Integer.toString(returnCode));
if (returnCode >= 2) {
    .out.println("OS Error: Unable to Find File or other OS error.");
    }

String line = "";
while (br.ready()) {
     String str = br.readLine();
     System.out.println(str);
     if (str.startsWith("line")) {
     //TODO: Report this error back to test tool.
     //System.out.println("Error!");
     }
     }

您需要耗盡進程的輸出和錯誤流,否則當執行的程序產生輸出時,它將阻塞。

流程文檔中

由於某些本機平台僅為標准輸入和輸出流提供了有限的緩沖區大小,因此無法及時寫入子流程的輸入流或讀取子流程的輸出流可能導致子流程阻塞,甚至死鎖。

讀取(並關閉) p.getInputStream()p.getErrorStream()

例如:

// com.google.common.io.CharStreams
CharStreams.toString(new InputStreamReader(p.getInputStream()));
CharStreams.toString(new InputStreamReader(p.getErrorStream()));

人們通常被exec例程掛在Java上。 我也曾經被那件事困擾過。 問題在於您嘗試執行的過程可能(取決於很多事情)可能首先寫入stdOut或stdErr。 如果您以錯誤的順序處理它們,則exec將掛起。 為了始終正確處理此問題,您必須創建2個線程以同時讀取stdErr和stdOut 像:

Process proc = Runtime.getRuntime().exec( cmd );

// handle process' stdout stream
Thread out = new StreamHandlerThread( stdOut, proc.getInputStream() );
out.start();

// handle process' stderr stream
Thread err = new StreamHandlerThread( stdErr, proc.getErrorStream() );
err.start();

exitVal = proc.waitFor(); // InterruptedException

...

out.join();
err.join();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM