2009-08-28 12 views
15

मैं आउटपुट संदेशों में संकलन-समय निरंतर के रूप में __LINE__ को शामिल करने का एक तरीका खोज रहा हूं।__LINE__ समकक्ष?

विभिन्न समाधान मौजूद हैं, लेकिन __LINE__ in JS और __LINE__ in C# में सुझाए गए बड़े रनटाइम पेनल्टी के साथ। वे आम तौर पर रन 4j के रूप में रनटाइम ऑब्जेक्ट StackFrame पर आधारित होते हैं।

आवश्यक आधार पर सक्षम/अक्षम करने की log4j संभावना का उपयोग करना एक विकल्प नहीं है, आमतौर पर जब कोई त्रुटि होती है, तो लाइन संख्या को सक्षम करने में बहुत देर हो चुकी है, और इनलाइन कोड में कोई लाइन नंबर नहीं लगता है और भी । यह संभव होगा करने के लिए या तो:

  1. पूर्व प्रक्रिया संकलन से पहले जावा स्रोत फ़ाइलें, ग्रहण के साथ एकीकृत कुछ के साथ आदर्श है, इसलिए यह भी developpement मंच पर परीक्षण किया जा सकता है।
  2. प्री-प्रोसेस लोडिंग समय पर कक्षा में सक्षम हो। उपरांत होने के बाद ओवरहेड नगण्य होगा।

1. असल में मैं प्रयोग करते हैं एक बदसूरत हैक: सिर्फ चींटी चाल

+0

बस मेरी जिज्ञासा के लिए: आपको लॉग में लाइन नंबर की आवश्यकता क्यों है? जब कोई त्रुटि होती है, तो आपके पास पूर्ण स्टैकट्रैक होता है, जो लाइन नंबर इंगित करता है ... – romaintaz

+3

कभी-कभी अपवाद में, लाइन नंबर के बजाय मेरे पास 'Util.java (इनलाइन संकलित कोड)' जैसा कुछ है। और कभी-कभी मेरे पास कोई अपवाद नहीं है, केवल लॉगिंग जानकारी: "यहां रहें", "यहां रहें", मैं अद्वितीय संदेश रखने से परेशान नहीं होना चाहता था (लाइन नंबर उन्हें वैसे भी अनूठा बनाता है) –

+0

JVM सक्षम होना चाहिए उस स्थिति को संभालें। जावा का आप किस संस्करण का उपयोग करते हैं? –

उत्तर

8

आप debug=line विकल्प के साथ संकलन, तो लाइन जानकारी वर्ग फ़ाइल में मौजूद है, लेकिन वीएम कि फेंक सकता रनटाइम पर । यह कुछ विकल्पों पर निर्भर करता है जिन्हें आप जावा प्रोग्राम प्रारंभ करते समय निर्दिष्ट कर सकते हैं। आम तौर पर, डीबग इंफोस के साथ चलने के लिए प्रदर्शन जुर्माना परम जीन स्पेस में लगभग 5% और थोड़ा अधिक स्मृति है। चूंकि यह जानकारी बहुत अमूल्य है, इसलिए मुझे इस जानकारी को पट्टी करने का कोई कारण नहीं दिखता है।

आपकी टिप्पणी (Util.java(Inlined Compiled Code)) सुझाव है कि आप आक्रामक अनुकूलन का उपयोग कर रहे हैं। यदि आप कर सकते हैं, तो उन्हें बंद कर दें। इस तरह, आप बस कर सकते हैं:

// For Java 1.4, use new Exception().getStackTrace() 
int line = Thread.currentThread().getStackTrace()[0].getLineNumber(); 

और जब आवश्यकता होती है (यानी catch या if (log.isInfoEnabled()) के अंदर)।

__LINE__ के लिए, जावा कंपाइलर के लिए इसका कोई समर्थन नहीं है। आपका एकमात्र विकल्प स्रोत को फ़िल्टर करने के लिए कुछ हैक्स का उपयोग करना है। मैं एक चर int __LINE__ को कहीं भी परिभाषित करने का सुझाव देता हूं और जब आपको इसकी आवश्यकता होती है तो कुछ यादृच्छिक मान (0 यादृच्छिक होने के लिए) सेट करें। फिर एक फ़िल्टर लिखें जो वर्तमान पंक्ति संख्या के साथ __LINE__ = \d+ में संख्या को प्रतिस्थापित करता है। यह जगह में लाइन नंबर को ठीक करने की अनुमति देता है।

+0

क्यों 'नया अपवाद()। थ्रेड.current थ्रेड()। GetStackTrace()' के बजाय getStackTrace() '? –

+0

कोई कारण नहीं, लेकिन तथ्य यह है कि मैंने वर्तमान स्टैक को पाने के लिए थ्रेड क्लास को खोजने के लिए परेशान नहीं किया था और मुझे पता था कि एक अपवाद में यह है :) –

+0

+1 एक समाधान के लिए जो मेरे देव वातावरण पर भी इस्तेमाल किया जा सकता है (बस निर्माण प्रक्रिया में लाइन नंबर के साथ 'थ्रेड ....' को खोजें और बदलें) –

13

यह सी में __LINE__ के प्रभाव जो संकलन में क्या होता है प्राप्त करने के लिए असंभव है के माध्यम से निर्माण सर्वर पर चेकआउट के बाद एक कस्टम पूर्वप्रक्रमक बुला पहर।

आप कार्यावधि में इस तरह एक समारोह को फोन करके लाइन नंबर प्राप्त कर सकते हैं,

public static int lineNumber() { 
    return Thread.currentThread().getStackTrace()[2].getLineNumber(); 
} 
+2

इस जानकारी तक पहुंचने के लिए लाइन के बारे में डीबग-जानकारी को कक्षा-फ़ाइल में संकलित किया जाना है। – Mnementh

0

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

हालांकि यदि आप अपना खुद का एनोटेशन प्रोसेसर लिखना चाहते हैं और जावा 6.0 compiler APIs का उपयोग करना चाहते हैं तो मुझे लगता है कि आप इस समस्या को हल कर सकते हैं। मुझे यह अनुमान लगाने की कोई परवाह नहीं होगी कि ऐसा करने के लिए कितना काम होगा।

ध्यान दें कि ग्रहण आपको अपने निर्माण तंत्र में अपनी एनोटेशन प्रोसेसिंग शामिल करने की अनुमति देता है।

0

मुझे जावा-कंपाइलर में ऐसी चीज के बारे में पता नहीं है। लेकिन आप एक साधारण प्रोग्राम लिख सकते हैं, जो फाइल में लिनेनंबर के साथ __LINE__ जैसे टोकन को प्रतिस्थापित करता है और संकलन से पहले इस टूल को निष्पादित करने के लिए अपने बिल्डप्रोसेस को कॉन्फ़िगर करता है। कुछ प्रकार के प्रीप्रोसेसर।

+0

यह वही है जो मैं बदलना चाहता हूं (फुटनोट देखें 1.) –

1

मैं इसके लिए एक लॉगिंग फ्रेमवर्क का उपयोग करता हूं, और इसे गन्दा विवरण से निपटने देता हूं। Java.util.logging और लॉगबैक दोनों आसानी से कॉलर के बारे में जानकारी लाइन प्रदान कर सकते हैं।

प्रमुख लाभ यह है कि जानकारी केवल तभी जरूरी है जब आवश्यक हो, इसलिए आउटपुट का मतलब ओवरहेड नहीं है।

5

यह सच है कि बॉक्स के बाहर, ये मैक्रोज़ उपलब्ध नहीं हैं। हालांकि, उपकरण का उपयोग करके, और डीबग जानकारी आप इसे लागू कर सकते हैं। चेक http://www.gallot.be/?p=85

4

मुझे पता चला है कि यह वर्ग चीजों को आसान बनाता है यदि आप "यहां पहुंच गए हैं, यहां पहुंच गए हैं" टाइपिंग लॉगिंग।

public class Here { 
    public static String at() { 
     StackTraceElement ste = Thread.currentThread().getStackTrace()[3]; 
     String where = ste.getClassName() + " " + ste.getMethodName() + " " + ste.getLineNumber() + " "; 
     return where; 
    } 
} 

इसके सरलतम रूप में इसका इस्तेमाल करने के लिए::

Log.v(TAG, Here.At()); 

या, अगर आप देखना चाहते हैं मैं एक फ़ाइल Here.java कि मैं अपनी परियोजनाओं में जोड़ देते हैं होता है सिर्फ निम्नलिखित वर्ग परिभाषा अन्य सामग्री:

Log.v(TAG, Here.At() + String.format("interesting value = %d", my_val)); 

इस पहले मामले में "com.otherpackagenamestuff.MyClass MyMethod 225" देना होगा, और एक ही लेकिन साथ "रोचक मूल्य = 123" दूसरे मामले में संलग्न।

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