2010-05-10 11 views
14

मेरे पास निम्नलिखित सिस्टम (डिक्टेड) एक सिस्टम में कक्षा है जिस पर मैं काम कर रहा हूं और FindbugsSE_BAD_FIELD चेतावनी उत्पन्न कर रहा है और मैं समझने की कोशिश कर रहा हूं कि यह क्यों कहेंगे कि इससे पहले कि मैंने इसे ठीक किया, होगा। कारण मैं उलझन में हूं क्योंकि वर्णन यह इंगित करता है कि मैंने वर्ग में अन्य गैर-धारावाहिक उदाहरण फ़ील्ड का उपयोग नहीं किया था, लेकिन bar.model.Foo भी serializable नहीं है और उसी तरह से उपयोग किया जाता है (जहां तक ​​मैं बता सकते हैं) लेकिन Findbugs इसके लिए कोई चेतावनी उत्पन्न नहीं करता है।एक Serializable जावा क्लास में लॉगर का उपयोग करने का सही तरीका क्या है?

import bar.model.Foo; 

import java.io.File; 
import java.io.Serializable; 
import java.util.List; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

public class Demo implements Serializable { 

    private final Logger logger = LoggerFactory.getLogger(this.getClass()); 
    private final File file; 
    private final List<Foo> originalFoos; 
    private Integer count; 
    private int primitive = 0; 

    public Demo() { 
     for (Foo foo : originalFoos) { 
      this.logger.debug(...); 
     } 
    } 

    ... 

} 

एक समाधान पर मेरी प्रारंभिक लाल कारखाने से एक लकड़हारा संदर्भ मैं इसका इस्तेमाल सही रूप में प्राप्त करने के लिए है:

public DispositionFile() { 
    Logger logger = LoggerFactory.getLogger(this.getClass()); 
    for (Foo foo : originalFoos) { 
     this.logger.debug(...); 
    } 
} 

कि हालांकि विशेष रूप से प्रभावी नहीं लगता है,।

विचार?

+2

Ceki ने बताया है कि के लिए logback getLogger (...) विधि तेजी से "पर्याप्त" जब जरूरत के नाम से जाना जाता है, और न सिर्फ इस्तेमाल किया एक स्थिर क्षेत्र में। –

+0

[लॉगर] (http://www.jcabi.com/jcabi-log/apidocs-0.7.7/com/jcabi/log/Logger.html) [jcabi-log] की कक्षा पर एक नज़र डालें (http://www.jcabi.com/jcabi-log/), जो एसएलएफ 4 जे – yegor256

+0

के आसपास एक रैपर है, एसएलएफ 1.5.3 या बाद में उपयोग करते समय [सेकी का जवाब] (http://stackoverflow.com/a/2818849/606662) पढ़ें। –

उत्तर

18

सबसे पहले, समय से पहले अनुकूलित न करें। यह हो सकता है कि LoggerFactory.getLogger() पर्याप्त तेज़ है, और निष्पादन समय के लिए कोई महत्वपूर्ण ओवरहेड योगदान नहीं देता है। अगर संदेह है, तो प्रोफाइल करें।

दूसरे, कारण यह है कि FindBugs Foo के उपयोग के बारे में शिकायत नहीं है, क्योंकि वर्ग प्रकार Foo के एक क्षेत्र नहीं है, यह प्रकार List के एक क्षेत्र है। जेनिक्स संकलन समय पर मिटा दिए जाते हैं, कक्षा में Foo के लिए कोई वास्तविक संदर्भ नहीं है, जहां तक ​​क्षेत्र परिभाषा का संबंध है। रनटाइम पर, Foo तथ्य यह है कि यदि आप Demo कक्षा के उदाहरण को क्रमबद्ध करने का प्रयास करते हैं तो गैर-धारावाहिक करने योग्य अपवाद का कारण बनता है, लेकिन findbugs इसे नहीं जान सकते हैं।

मेरी पहली प्रतिक्रिया Logger एक आवृत्ति फ़ील्ड के बजाय एक स्थिर क्षेत्र बनाना होगा। इस स्थिति में ठीक काम करना चाहिए।

public class Demo implements Serializable { 
    private static final Logger logger = LoggerFactory.getLogger(Demo.class); 

    // .. other stuff 
} 
+0

नाइटपिक: Findbugs यह जान सकते हैं: किसी फ़ील्ड के घोषित प्रकार (किसी भी प्रकार के पैरामीटर/वाइल्डकार्ड समेत) क्लासफ़ाइल पर लिखा गया है और इसलिए स्थिर विश्लेषण के लिए उपलब्ध है। – meriton

+1

आह, नहीं यह नहीं कर सकता: Findbugs नहीं जानता कि एक सूची वास्तव में प्रकार टी का एक गैर-क्षणिक संदर्भ रखेगी (संग्रह .emptyList() द्वारा लौटाई गई एक सूची उदाहरण के लिए नहीं है)। – meriton

+0

मेरा obfuscation बहुत प्रभावी था! :) वास्तविक वर्ग में उस सूची के कई संदर्भ हैं। मैं अंतरिक्ष के लिए संपीड़ित करने की कोशिश कर रहा था। यह आपके जवाब को कैसे बदल देगा? प्रतिक्रिया के लिए अब तक धन्यवाद! –

7

मैं नहीं चाहता कि चीजें टेंगेंट पर उतर जाएं, लेकिन क्या आपने लॉगर्स का पारंपरिक प्रारंभिक माना है?

private static final Logger logger = LoggerFactory.getLogger(Demo.class); 

यदि आपको प्रत्येक उदाहरण (जो असामान्य है) के लिए वास्तव में अलग-अलग लॉगर्स की आवश्यकता नहीं है, तो समस्या दूर हो जाएगी।

वैसे, SL4J की author कहा (जैसे कॉमन्स-लॉगिंग Log4J रैपर के एक critique में),

प्रायः

, इन रैपर संदिग्ध गुणवत्ता के इस तरह के हैं कि की लागत निष्क्रिय (या अक्षम) लॉगिंग बयान प्रत्यक्ष लॉग 4j उपयोग की तुलना में 1'000 (एक हजार) के कारक से गुणा किया जाता है। रैपर वर्गों में सबसे आम त्रुटि प्रत्येक लॉग अनुरोध पर Logger.getLogger विधि का आविष्कार है। यह आपके एप्लिकेशन के प्रदर्शन पर विनाश को समाप्त करने की गारंटी देता है। वास्तव में!!!

यह सुझाव देगा कि प्रत्येक बार जब आपको आवश्यकता हो तो लॉगर प्राप्त करने का आपका वैकल्पिक विचार अनुशंसित नहीं है।

+0

निष्पक्ष होने के लिए, उस लेख की अगली वाक्य कहती है "बेशक, सभी रैपर खराब गुणवत्ता वाले नहीं हैं। उदाहरण के लिए, कॉमन्स-लॉगिंग एपीआई एक उचित कार्यान्वयन का एक प्रमुख उदाहरण है।" –

+0

इसके अलावा तर्कसंगत रूप से लॉगर्स हमेशा स्थिर होना चाहिए जब तक आपको गतिशील लॉगर नाम की आवश्यकता न हो या उप-वर्गों या किसी भी चीज़ के साथ उदाहरण साझा न करें, तो उसके लिए +1। –

6

FindBugs इस विशेष मामले में आप को गुमराह क्योंकि org.slf4j.Logger इंटरफ़ेस नहीं java.io.Serializable के रूप में चिह्नित है। हालांकि, एसएलएफ 4 जे लॉगर कार्यान्वयन जो एसएलएफ 4 जे के साथ सभी समर्थन क्रमबद्धता के बाहर जहाज का समर्थन करते हैं। कोशिश करो। आप देखेंगे कि यह काम करता है। स्थैतिक चर को

विपरीत, उदाहरण चर डिफ़ॉल्ट रूप से क्रमानुसार लगे हुए हैं:

यहाँ SLF4j पूछे जाने वाले प्रश्न से एक अंश है। SLF4J संस्करण 1.5.3 के रूप में, लॉगर उदाहरण serialization जीवित रहते हैं। इस प्रकार, होस्ट क्लास संख्या के क्रमशः किसी भी विशेष कार्रवाई, की आवश्यकता होती है जब भी लॉगर्स इंस्टेंस चर के रूप में घोषित किए जाते हैं। पिछले संस्करणों में, को लॉगर उदाहरणों को मेजबान कक्षा में क्षणिक घोषित किया जाना चाहिए।

भी देखें http://slf4j.org/faq.html#declared_static

+0

शायद वह 1.5.3 से पुराने संस्करण का उपयोग कर रहा है, उस स्थिति में – skaffman

+1

FindBugs शायद भ्रमित हो जाता है क्योंकि org.slf4j.Logger इंटरफ़ेस को SLF4J संस्करण 1.5.3 और बाद में भी Serializable के रूप में चिह्नित नहीं किया जाता है। – Ceki

3

मेरे आरंभिक प्रतिक्रिया आश्चर्य अगर यह भी समझ में आता है अपने वस्तु में एक लॉगर उदाहरण क्रमानुसार करने है। जब आप इसे बाद में deserialize, क्या यह वास्तव में लॉगजर के पर्यावरण को सही होने की अपेक्षा करने के लिए उचित है? मुझे लगता है कि मैं नहीं बल्कि सिर्फ इस के साथ जा सकते हैं और यह एक दिन कहेंगे:

private transient Logger logger = LoggerFactory.getLogger(this.getClass()); 
+2

... जब तक आप deserialization पर इसे फिर से बनाने के लिए कदम उठाते हैं। – EJP

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