2011-12-21 11 views
19

मैं (सत्यापन स्क्रिप्ट निष्पादित करता है) बिना किसी समस्या के कमांड लाइन से इस आदेश को चला सकते हैं:जावा 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 

और जावा से अगर मैं URL पैरामीटर को बंद रखना होगा और बस कार्य करें:

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

यह ठीक काम करता है। यदि मैं पैरामीटर के लिए कुछ यूआरएल का उपयोग करता हूं जैसे:

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

यह भी ठीक काम करता है।

लेकिन अगर मैं इस विशेष यूआरएल https://das.dynalias.org:8080/das_core/das/2.16.840.1.113883.4.349/1012581676V377802/otherAdminData/careCoordinators का उपयोग करता हूं, तो स्क्रिप्ट बस लटकती है (जावा प्रक्रिया समाप्त होने की प्रतीक्षा करता है)। मुझे यकीन नहीं है कि यह उस यूआरएल के लिए कमांड लाइन से क्यों काम करता है लेकिन जावा प्रोग्राम से नहीं। मैंने 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!"); 
    } 
    } 
+0

शायद वर्तमान निर्देशिका कोई फर्क पड़ता है? आप कमांड लाइन में दूसरी निर्देशिका में स्विच करने का प्रयास कर सकते हैं। – Yogu

+0

आपको जावा से निष्पादित वास्तविक कमांड लाइन की जांच करनी चाहिए, लिनक्स पर - 'ps f', Win-sysinternals ProcessExplorer –

+1

पर यह कुछ एसएसएल समस्या हो सकती है। क्या आप इसे सत्यापित करने के लिए http endpoint को कॉल करने का प्रयास कर सकते हैं? – phoet

उत्तर

17

आप प्रक्रिया के उत्पादन और त्रुटि धाराओं के निकास के लिए की जरूरत है, या जब निष्पादित कार्यक्रम उत्पादन का उत्पादन वरना यह रोकेंगे।

Process documentation से

:

क्योंकि कुछ स्थानीय प्लेटफ़ॉर्म केवल मानक इनपुट और आउटपुट धाराओं के लिए सीमित बफर आकार प्रदान करते हैं, तुरंत इनपुट धारा लिखने या उपप्रक्रिया के उत्पादन धारा को पढ़ने के लिए विफलता के लिए उपप्रक्रिया कारण हो सकता है ब्लॉक, और यहां तक ​​कि डेडलॉक भी।

+0

मुझे प्रक्रिया के लिए एक नाली विधि नहीं मिली। मैं वास्तव में कौन सा कोड चलाऊंगा? मैंने पूर्ण कोड के साथ प्रश्न अद्यतन किया है। उत्पादन और त्रुटि धाराओं को निकालने के लिए – user994165

+1

बस करें: इनपुटस्ट्रीम = = ...; in.skip (in.available()); इनपुटस्ट्रीम त्रुटि = ...; err.skip (err.available()); –

+1

@ user994165 धाराओं को निकालने के लिए नमूना कोड है [यहां] (http://stackoverflow.com/a/7962434/523391) – prunge

7

p.getInputStream() और p.getErrorStream() पढ़ें (और बंद करें)।

उदाहरण के लिए:

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

क्या होगा यदि आउटपुट जावा की ढेर मेमोरी से बड़ा है? हालांकि मुझे लगता है कि ज्यादातर मामलों में आप जानते हैं कि यह नहीं होगा। यदि आप इस तरह की कोई विधि लिखते हैं तो एक समस्या उत्पन्न हो सकती है, और फिर इस सीमा को भूलने के बाद बड़े आउटपुट का उत्पादन करने वाले किसी चीज़ पर इसका उपयोग करें। –

+0

@EvgeniSergeev यह सही है, उन्हें एक और तरीके से पढ़ें और बंद करें, मैंने अभी उन्हें उदाहरण के रूप में वर्णित किया है। –

7

लोग आमतौर पर जावा में कार्यकारी दिनचर्या रुक जाता है द्वारा पकड़ा गया। मुझे उस बार भी सोचा गया था। समस्या यह है कि जिस प्रक्रिया को आप निष्पादित करने का प्रयास कर रहे हैं (कई चीजों के आधार पर) या तो पहले stdOut या stdErr को लिख सकते हैं। यदि आप उन्हें गलत क्रम में संभालते हैं तो exec लटका होगा। इसे सही ढंग से संभालने के लिए आपको हमेशा stdErr और stdOut पढ़ने के लिए 2 थ्रेड बनाना होगा। एसएचएच:

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(); 
+1

रीडायरेक्ट एररस्ट्रीम का उपयोग करना एक बेहतर विचार है: http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ProcessBuilder.html#redirectErrorStream%28boolean%29 –

संबंधित मुद्दे