2015-02-06 9 views
5

पर लिखते समय जेटी के नीचे लटकती है मुझे एक समस्या मिली है जहां एक साझा लाइब्रेरी जिसे जेटी के तहत जेएनए के साथ बुलाया जाता है, stderr पर प्रिंट करते समय अटक जाता है।साझा सी लाइब्रेरी (जेएनआई) sttyr

मैंने पहली बार एक बहुत ही सरल सी साझा लाइब्रेरी बनाने के द्वारा पुन: पेश करने में समस्या को सरल बना दिया है जो 10012 बार कॉल करने के लिए कुछ भी नहीं करता है, फिर वापस लौटें।

जावा पक्ष पर हमारे पास एक वैश्विक लॉक पर एक सिंक्रनाइज़ स्टेटमेंट है ताकि यह सुनिश्चित किया जा सके कि एक समय में साझा लाइब्रेरी में केवल एक थ्रेड है।

synchronized (lock) { 
    Foo.INSTANCE.shared_lib_function(); 
} 

मैं घाट के तहत इस तैनाती और साझा लाइब्रेरी अंत में (कम से कम 100 अनुरोधों के बाद) फोन मुझे लगता है कि शेयर की गई लाइब्रेरी अटक जाती है करने के लिए घाट के लिए निरंतर अनुरोध करती हैं।

jstack इस्तेमाल करते हुए हम धागा जो साझा लाइब्रेरी में कॉल के अंदर फंस गया है (कक्षा का नाम बदला गया है) देख सकते हैं:

Thread 5991: (state = BLOCKED) 
- com.whats.going.on.connector.MyFooCaller.callIt() @bci=55, line=105 (Interpreted frame) 
- com.whats.going.on.Controller.callSharedLib() @bci=101, line=71 (Interpreted frame) 
- com.whats.going.on.Controller$$FastClassBySpringCGLIB$$d6a0f4b3.invoke(int, java.lang.Object, java.lang.Object[]) @bci=72 (Interpreted frame) 
- org.springframework.cglib.proxy.MethodProxy.invoke(java.lang.Object, java.lang.Object[]) @bci=19, line=204 (Interpreted frame) 
- org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint() @bci=19, line=717 (Interpreted frame) 
- org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() @bci=19, line=157 (Interpreted frame) 
- org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(org.aopalliance.intercept.MethodInvocation) @bci=7, line=64 (Interpreted frame) 
- org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() @bci=101, line=179 (Interpreted frame) 
- org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], org.springframework.cglib.proxy.MethodProxy) @bci=112, line=653 (Interpreted frame) 

gdb का उपयोग करते हुए मैं अपने साझा लाइब्रेरी से एक नामों को प्राप्त करने में सक्षम हूँ:

#0 0x00007f1136ec153d in write() from /lib64/libc.so.6 
#1 0x00007f1136e57ad3 in _IO_new_file_write() from /lib64/libc.so.6 
#2 0x00007f1136e5799a in _IO_new_file_xsputn() from /lib64/libc.so.6 
#3 0x00007f1136e4da4d in fwrite() from /lib64/libc.so.6 
#4 0x00007f10ed2dc122 in shared_lib_function() at foo/bar.c:357 
#5 0x00007f10ed4d227c in ??() 
#6 0x000000000000000e in ??() 
#7 0x00007f110c2309c0 in ??() 
#8 0x00007f110c230700 in ??() 
#9 0x00007f10ed4d1ddf in ??() 
#10 0x0000000000000000 in ??() 

लाइन 357 fprintf() लाइन है।

मुझे चिंतित था कि शायद यह मुद्दा केवल स्टडआउट से पढ़ना और कभी भी stderr से अटक रहा था। जावा के भीतर मैंने एक धागा बनाया जो stdout और stderr को प्रिंट करता रहता है और मैं दोनों को देख सकता हूं।

मैंने यह भी देखने की कोशिश की कि क्या होगा यदि हमने जावा के भीतर System.err.println(""); पर 100 कॉल किए थे और हालांकि, जावा में थ्रेड फेंकने का कारण नहीं था।

मूल रूप से जब यह stderr प्रवेश करने और stdout के साथ पुनः निर्देशित किया गया था:

PrintStream errorLog = new PrintStream(new RolloverFileOutputStream(new Fil("yyyy_mm_dd.error.log").getCanonicalPath(), false, 90)); 
System.setErr(errorLog); 
System.setOut(errorLog); 

मैं देखना है कि क्या साझा lib लॉग फ़ाइल में stderr करने के लिए लिख रहा था सक्षम था। इसके बाद मैंने stderr और stdout के पुनर्निर्देशन को हटा दिया और देखा कि मैं अब नहीं देख सकता था कि साझा लाइब्रेरी stderr को क्या लिख ​​रहा था, हालांकि मैं देख सकता था कि System.err.println() प्रिंटिंग था।

जब मैंने एक साझा (बिना जेटी के) साझा लाइब्रेरी को कॉल करने का प्रयास किया तो मैं समस्या को पुन: उत्पन्न करने में असमर्थ था। मैंने ग्रहण और मेवेन दोनों से अपना परीक्षण चलाया। मैंने उपरोक्त के रूप में stderr और stdout को पुनर्निर्देशित करने का भी प्रयास किया, हालांकि मुझे पता चला कि केवल जावा के भीतर stderr और stdout को लिखना था (यानी fprintf() साझा पुस्तकालय के भीतर से stderr को ग्रहण में या कंसोल में दिखाना जारी रखा गया था)।

जावा संस्करण:

java version "1.8.0_25" 
Java(TM) SE Runtime Environment (build 1.8.0_25-b17) 
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode) 

जेट्टी संस्करण: 9.2.6.v20141205

+0

जेएनए ['Native.synchronizedLibrary()'] प्रदान करता है (http://twall.github.io/jna/4.1.0/com/sun/jna/Native.html#synchronizedLibrary (com.sun.jna.Library)) किसी भी समय किसी भी समय एक कॉल पर मूल पुस्तकालय तक पहुंच प्रतिबंधित करने के उद्देश्य से। – technomage

उत्तर

0

समस्या मैं था YAJSW केवल अभी तक घाट के System.out और System.err से पढ़ रहा था था पर comp.lang.java.programmer समूह में पाया जा सकता है किसी भी साझा लाइब्रेरी के स्टडआउट या स्टेडर से नहीं पढ़ना जो कुछ त्रुटि होने पर अंततः भर जाएगा।

समाधान = wrapper.console.pipestreams सेट करने के लिए सच है, को देखने के http://yajsw.sourceforge.net/YAJSW%20Configuration%20Parameters.html

मतलब समय में काम किया है freopen साथ stdout और stderr रीडायरेक्ट किया जा रहा था। आपकी सहायता के लिए धन्यवाद.

0

JNI से STDERR को लिखते हुए, सबसे जावा प्रवेश चौखटे के साथ अच्छा नहीं खेलेंगे।

विकल्प # 1: जावा साइड फिक्स

आप करने की आवश्यकता होगी क्या:

  • जेट्टी के डिफ़ॉल्ट लॉगिंग मॉड्यूल का उपयोग न करें
  • जेट्टी के StdErrLog कार्यान्वयन का उपयोग न करें
  • वैकल्पिक लॉगिंग ढांचे को कॉन्फ़िगर करें। slf4j से शुरू करें और लॉगबैक या log4j जैसे कुछ का उपयोग करने के लिए इसे सेट करें।
  • STDERR को कैप्चर न करने के लिए अपने वैकल्पिक लॉगिंग फ्रेमवर्क को कॉन्फ़िगर करें।
  • एसटीडीईआरआर को लिखने के लिए अपने वैकल्पिक लॉगिंग फ्रेमवर्क को कॉन्फ़िगर करें, क्या यह केवल लॉग फ़ाइल को लिखता है। करने के लिए कभी नहीं डिफ़ॉल्ट stderr या stdout उत्पादन धाराओं JNI साइड फिक्स

    एक अन्य विकल्प अपने JNI कोड लिखने के लिए:

विकल्प # 2। लेकिन इसके बजाय जावा सिस्टम.एर और System.out में फ़ाइल हैंडल संदर्भ प्राप्त करें और इसके बजाय उनको लिखें।

कि का एक उदाहरण

https://groups.google.com/forum/#!msg/comp.lang.java.programmer/SUN7EEjk8AU/JWjGGaD0ey0J

+0

जोकिम "जेएनआई से एसटीडीईआरआर को लिख रहा है, ज्यादातर जावा लॉगिंग ढांचे के साथ अच्छा नहीं खेलेंगे" एक ज्ञात समस्या? क्या इसकी सूचना मिली है? – Luke

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