2011-09-19 5 views
6

समाप्त नहीं किया गया है, मैं एक उपप्रोसेस शुरू करने के लिए जावा की प्रोसेसबिल्डर का उपयोग कर रहा हूं, जो एक और जावा प्रोग्राम है जिसे एक अलग जेवीएम में चलाना है।प्रतीक्षाफोर का उपयोग कर जावा खत्म से उपप्रोसेस शुरू हुआ लेकिन स्ट्रीम को

मैं प्रक्रिया से stdout और stderr धाराओं से पढ़ने के लिए दो थ्रेड शुरू करता हूं, ताकि स्ट्रीम बफर भरने पर कोई लटका न हो। Process.waitFor पर कॉल लौटाता है लेकिन धाराएं समाप्त नहीं होती हैं।

कोड मैं दिखता है की तरह कुछ का उपयोग कर रहा (कमांड स्ट्रिंग की एक सूची है):

ProcessBuilder pb = new ProcessBuilder(command); 

final Process p = pb.start(); 
final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); 
final ByteArrayOutputStream errStream = new ByteArrayOutputStream(); 

Thread outputThread = new Thread() { 
    @Override 
    public void run() { 
     try { 
      IOUtils.copy(p.getInputStream(), outStream); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    }; 
}; 
outputThread.start(); 

Thread errorThread = new Thread() { 
    @Override 
    public void run() { 
     try { 
      IOUtils.copy(p.getErrorStream(), errStream); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    }; 
}; 
errorThread.start(); 

int returncode = p.waitFor(); 
outputThread.join(); 
errorThread.join(); 

अगर मैं इस तरह के "जावा -संस्करण" या "dir" या कुछ और, कोड के रूप में कुछ और, चलाने ठीक काम करता है। मेरे पास जावा कोड तक पहुंच है जिसे मैं चलाने की कोशिश कर रहा हूं, लेकिन मैंने कभी नहीं सुना है कि आपको System.out पर नज़दीकी() कॉल करना चाहिए।

+0

आप प्रक्रिया को बंद करने के बारे में मेरे सवाल में दिलचस्पी हो सकती उचित धाराओं: http://stackoverflow.com/questions/7065067/how-to-close-std -स्ट्रीम-से-जावा-लैंग-प्रोसेस-उपयुक्त एक और उपयोगी लिंक: http://mark.koli.ch/2011/01/leaky-pipes-remember-to-close-your-streams-when-using- javas-runtimegetruntimeexec.html –

+0

यदि मैं 'IOUtils.closeQuietly' का उपयोग करता हूं या 'join()' कॉल से पहले स्ट्रीम पर 'क्लोज़()' को कॉल करता हूं, तो प्रोग्राम उस कॉल पर लटकता है। –

+0

यह शायद सबसे अधिक है क्योंकि 'IOUtils.copy (in, out)' 'इनपुटस्ट्रीम.read (बाइट []) 'का उपयोग करता है और यह अवरुद्ध है और आने वाले डेटा की प्रतीक्षा कर रहा है। इसलिए धागे हमेशा के लिए चल रहे हैं और इसलिए 'शामिल() 'हमेशा के लिए इंतजार कर रहा है। दिए गए टाइमआउट के बाद आपको यहां बंद करना होगा। कृपया आपके द्वारा दिए गए लिंक से मेरे उत्तर में पोस्ट किए गए एक कार्यान्वयन को आजमाएं। मैं शर्त लगाऊंगा कि यह इसे यहां संभाल सकता है। –

उत्तर

0

जैसा कि मुझे this website से पता है, आपको प्रक्रिया ऑब्जेक्ट से सभी std-streams को अपने आप बंद करना होगा। भले ही पहले इस्तेमाल किया गया हो या नहीं। यह जी 1 कचरा कलेक्टर से अत्यधिक प्रतीत होता है (जावा 7 afaik के बाद से डिफ़ॉल्ट) जो स्पष्ट रूप से बंद नहीं होने पर पाइप खुलता रहता है - यहां तक ​​कि जब उपप्रोसेस समाप्त हो जाता है।

मैं यहां आंतरिक से परिचित नहीं हूं लेकिन मेरे प्रश्न में my answer में पोस्ट किया गया कोड GhostScript और दूसरों को बहुत कुछ 24/7 सिस्टम पर ठीक काम करता है।

अन्य प्रश्न और एसओ करते हुए कहा कि आप प्रक्रिया 'एसटीडी-धाराओं स्पष्ट को बंद करना होगा पर जवाब:

3

अपाचे कॉमन्स कार्यकारी आप के लिए यह सब करता है। एक बहुत अधिक करने के लिए आसान ...

http://commons.apache.org/exec/

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