मैं जावा में वर्तमान स्टैक ट्रेस कैसे प्राप्त कर सकता हूं?


1001

मुझे जावा में वर्तमान स्टैक ट्रेस कैसे मिलता है , जैसे .NET में आप कैसे कर सकते हैं Environment.StackTrace?

मैंने पाया Thread.dumpStack()लेकिन यह वह नहीं है जो मैं चाहता हूं - मैं स्टैक ट्रेस वापस लेना चाहता हूं, इसे प्रिंट नहीं करना चाहता हूं।


73
जब मैं एक्लिप्स में डीबगिंग कर रहा होता हूं, तो मैं एक घड़ी अभिव्यक्ति के रूप में "नए अपवाद ()। PrintStackTrace ()" का उपयोग करता हूं। यह आसान है जब आप एक ब्रेकपॉइंट पर निलंबित करते हैं और जानना चाहते हैं कि आप कहां से आए हैं।
टिम ब्यूथ

22
@ टिमबुटे: जब आप डिबग मोड में हैं तो ग्रहण आपको पहले से ही स्टैक ट्रेस नहीं बता रहा है? मुझे ऐसा लगता है।
लुइगी मस्सा गैलेरानो

41
Arrays.toString (Thread.currentThread () getStackTrace ()।); काफी सरल।
अजय

2
@ अरकॉन यह जावा को संदर्भित करता है, और यह दिखा रहा है कि वे इसे .net में कैसे करेंगे और जावा में समकक्ष क्या है।
पोकेचू 22

9
इसे अच्छी तरह से प्रिंट करने के लिए आप अपाचे का उपयोग कर सकते हैं StringUtils: StringUtils.join (currentTread ()। GetStackTrace (), "\ n");
आर्ट

जवाबों:


1158

आप उपयोग कर सकते हैं Thread.currentThread().getStackTrace()

यह एक सरणी देता है जो StackTraceElementकिसी प्रोग्राम के वर्तमान स्टैक ट्रेस का प्रतिनिधित्व करता है।


48
अगर आप पहले से ही अपाचे कॉमन्स का उपयोग कर रहे हैं, तो एक अच्छा वन-लाइनर एक स्ट्रिंग पाने के लिए: String fullStackTrace = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e); stackoverflow.com/a/10620951/11236
ripper234

5
सरणी में पहला तत्व (इंडेक्स 0) java.lang.Thread.getStackTrace मेथड है, दूसरा (इंडेक्स 1) आमतौर पर ब्याज का पहला है।
lilalinux

175
स्टैक ट्रेस को स्ट्रिंग में बदलने के लिए एक लाइनर जो तब काम करता है जब आपके पास कोई अपवाद नहीं होता है और आप Apache Arrays.toString (Thread.currentThread ()। GetStackTrace ())
टोनी

9
@ यह समाधान बेहतर है क्योंकि इसे
फेंकने

3
जैसा कि नीचे दिए गए कई जवाबों में बताया गया है - new Throwable().getStackTrace()यह बहुत तेज़ है, क्योंकि इसे जांचने की आवश्यकता नहीं है this != Thread.currentThread()और संभावित जेवीएम ओवरहेड्स को चाइल्ड-क्लास के माध्यम से कॉल करने की आवश्यकता है ( Exception extends Throwable)
व्लाद

264
Thread.currentThread().getStackTrace();

ठीक है अगर आपको परवाह नहीं है कि स्टैक का पहला तत्व क्या है।

new Throwable().getStackTrace();

आपके मौजूदा तरीके के लिए एक परिभाषित स्थिति होगी, अगर यह मायने रखता है।


35
(new Throwable()).getStackTrace()बहुत तेज़ी से क्रियान्वित हो रहा है (देखें बग्ससून.com
bugdatabase

2
क्या आप अधिक विस्तार से बता सकते हैं कि कैसे Thread.currentThread ()। GetStackTrace () के परिणाम नए Throwable () से भिन्न हो सकते हैं। getStackTrace ()? मैंने दोनों की कोशिश की और पाया कि Thread.currentThread ()। GetStackTrace () index 0 में array.getStackTrace के साथ सरणी देता है और कॉलिंग विधि इंडेक्स 1 में है। नया थ्रोबेबल ()। GetStackTrace () विधि कॉलिंग के साथ एक सरणी देता है। इंडेक्स 0. पर विधि। ऐसा लगता है कि दोनों विधियों में वर्तमान पद्धति के लिए एक परिभाषित स्थिति है लेकिन स्थिति अलग हैं। क्या कोई और अंतर है जो आप इंगित कर रहे हैं?
रयान

9
@ रेयान, कोई गारंटी नहीं है कि Thread.currentThread ()। GetStackTrace () विधि के विभिन्न संस्करणों पर उस स्थिति को बनाए रखने का वादा नहीं करता है। इसलिए जब आप जाँच करते हैं कि यह सूचकांक १ पर था। सूर्य के लिए जेवीएम (१.५ या १.६, याद नहीं है) के कुछ संस्करण पर, यह सूचकांक २ था। यही वह है जो मुझे परिभाषित स्थिति से मतलब है - कल्पना के लिए कॉल यह वहाँ रहना है, और भविष्य में वहाँ रहना है।
यिशै

5
@MightyE बग को अब जावा 6 में तय किए गए अनुसार बंद कर दिया गया है। इंटर्नल को देखते हुए, ऐसा लग रहा है कि यह (new Exception()).getStackTrace()तब होता है जब अनुरोधित स्टैक ट्रेस वर्तमान थ्रेड पर होता है (जो हमेशा के लिए होगाThread.currentThread().getStackTrace();
एम। जस्टिन

3
@MJustin: बग "तय" नहीं है, जैसा कि रिपोर्ट किया गया है, यह ताकतवर ने टिप्पणी लिखने से छह साल पहले भी तय किया है। वास्तव में, यह तय किया गया है पहले भी Stackoverflow स्थापित किया गया है ...
होल्गर

181
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
    System.out.println(ste);
}

20
जावा में थ्रोबेबल पर परिभाषित एक प्रिंटस्ट्रेस विधि है, आप कर सकते हैं: new Exception().printStackTrace(System.out)जिसे मैं याद रख सकता हूं, लूप के लिए संभवतः कम ओवरहेड है, लेकिन आपको इसे केवल डिबगिंग चीज़ के रूप में उपयोग करना चाहिए ...
जाप

2
मुझे यह सबसे अच्छा लगता है क्योंकि आपको अपने प्रिंटल स्टेटमेंट को लपेटकर, शोर मचाने का मौका मिलता है, जैसेfor (StackTraceElement ste : Thread.currentThread().getStackTrace()) { if(ste.toString().contains("mypackages")){ System.out.println(ste); } }
nby

61
Thread.currentThread().getStackTrace();

JDK1.5 के बाद से उपलब्ध है।

एक पुराने संस्करण के लिए, आप अनुप्रेषित कर सकते हैं exception.printStackTrace()एक करने के लिए StringWriter():

StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();

3
new Throwable().getStackTrace()JDK1.4 के बाद से उपलब्ध है ...
होल्गर

40

आप उसके लिए अपाचे के कॉमन्स का उपयोग कर सकते हैं:

String fullStackTrace = org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);

13
यह एक अच्छा एक लाइन समाधान है। FYI करें, किसी को भी उपयोग करने के लिए org.apache.commons.lang3, पूरी लाइन है:org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
फाइलऑफसेट

2
बस जब org.apache.commons.lang3मैं शुरू में अनदेखी की है, जो आयात करने के लिए fileoffset की टिप्पणी को दोहराने के लिए - आयात के lang3बजाय का उपयोग करता है lang, और के getFullStackTraceसाथ बदल देता है getStackTrace
15 किमी पर ggkmath

यह बहुत उपयोगी है! जब एक IDE (उदाहरण के लिए, IntelliJ IDEA) का उपयोग कर डिबगिंग होता है, तो ExceptionUtils.getStackTrace(new Throwable())स्टैक ट्रेस प्राप्त करने के लिए अभिव्यक्ति का उपयोग करना बहुत अच्छा है ।
सेर्गेई ब्रूनोव

24

एंड्रॉइड पर इसका उपयोग करने का एक आसान तरीका है:

import android.util.Log;
String stackTrace = Log.getStackTraceString(exception); 

4
GetStackTraceString को कहाँ परिभाषित किया गया है? क्या यह किसी तृतीय पक्ष लॉगिंग लाइब्रेरी से है?
स्किपहोप्पी

6
android.util.Log.get.ackStackTraceString डेवलपर.
Ondrej Kvasnovsky

22

सभी थ्रेड्स का स्टैक ट्रेस प्राप्त करने के लिए आप या तो jstack यूटिलिटी, JConsole का उपयोग कर सकते हैं या एक किल -क्विट सिग्नल (एक पॉज़िक्स ऑपरेटिंग सिस्टम पर) भेज सकते हैं।

हालाँकि, यदि आप यह प्रोग्रामेटिक रूप से करना चाहते हैं तो आप ThreadMXBean का उपयोग करके देख सकते हैं:

ThreadMXBean bean = ManagementFactory.getThreadMXBean();
ThreadInfo[] infos = bean.dumpAllThreads(true, true);

for (ThreadInfo info : infos) {
  StackTraceElement[] elems = info.getStackTrace();
  // Print out elements, etc.
}

जैसा कि उल्लेख किया गया है, यदि आप केवल वर्तमान थ्रेड के स्टैक ट्रेस चाहते हैं तो यह बहुत आसान है - बस उपयोग करें Thread.currentThread().getStackTrace();


2
इस उत्तर में कोड स्निपेट जेएमएम को क्विट सिग्नल (यूनिक्स की तरह सिस्टम) या <ctrl> <ब्रेक> विंडोज पर भेजने पर आपके द्वारा देखे जाने वाले प्रोग्राम को बनाने के लिए निकटतम रूप से आता है। अन्य उत्तरों के विपरीत आपको मॉनिटर और सिंक्रोनाइज़र के साथ-साथ सिर्फ स्टैक के निशान भी मिलते हैं (जैसे कि यदि आप StackTraceElement सरणी पर पुनरावृति करते हैं और System.err.println(elems[i])प्रत्येक पर करते हैं)। स्निपेट में दूसरी पंक्ति bean.पहले गायब है , dumpAllThreadsलेकिन मुझे लगता है कि ज्यादातर लोग इसे बाहर काम कर सकते हैं।
जॉर्ज हॉकिन्स

22

एक अन्य समाधान (केवल 35 31 वर्ण):

new Exception().printStackTrace();   
new Error().printStackTrace();

1
भयानक समाधान। अब मुझे सभी स्टैक फ़्रेमों के माध्यम से लूप नहीं करना है
विनील कोवुरी


17

टोनी ने स्वीकार किए गए उत्तर की टिप्पणी के रूप में, वही दिया जो सबसे अच्छा उत्तर लगता है जो वास्तव में ओपी के प्रश्न का उत्तर देता है :

Arrays.toString(Thread.currentThread().getStackTrace()).replace( ',', '\n' );

... ओपी ने यह नहीं पूछा कि Stringस्टैक ट्रेस से कैसे प्राप्त किया जाए Exception। और हालांकि मैं अपाचे कॉमन्स का बहुत बड़ा प्रशंसक हूं, जब ऊपर से कुछ सरल है तो बाहर की लाइब्रेरी का उपयोग करने का कोई तार्किक कारण नहीं है।


मेरे पास थ्रेड्स की एक सूची है और मुझे उनके स्टैक के निशान प्रिंट करने की आवश्यकता है।
डैनियल एस। यित्सकोव

उस स्थिति में, सुनिश्चित करें कि आप उपयोग करते हैं Thread.getAllStackTraces()जो आपको देता है Map<Thread, StackTraceElement[]>। जब भी किसी को सुरक्षित करने की आवश्यकता होगी, हॉटस्पॉट सभी थ्रेड्स को सुरक्षित करेगा। ज़िंग दूसरे को परेशान किए बिना अलग-अलग थ्रेड्स को सुरक्षित स्थान पर ला सकता है। स्टैकट्रेस प्राप्त करने के लिए एक सुरक्षित स्थान की आवश्यकता होती है। Thread.getAllStackTraces()सभी स्टैक के निशान हो जाते हैं और केवल एक बार सभी थ्रेड्स को रोक देता है। बेशक, आपको यह पता लगाना चाहिए कि आप वास्तव में किस मैपिंग में रुचि रखते हैं।
राल्फ एच।

14

मेरा सुझाव है कि

  Thread.dumpStack()

एक आसान तरीका है और इसका फायदा यह है कि वास्तव में एक अपवाद या फेंकने योग्य नहीं है जब कोई समस्या नहीं हो सकती है, और बिंदु के लिए काफी अधिक है।


1
ठीक है, वास्तव में, डंपस्टैक () एक स्थिर विधि है, और इसे स्थिर तरीके से एक्सेस किया जाना चाहिए। धन्यवाद, ग्रहण!
थॉमस एडकिंस

1
मुझे शॉर्टकट पसंद है, लेकिन इस विधि के लिए स्रोत कोड है: new Exception("Stack trace").printStackTrace();इसलिए यह वास्तव में एक थ्रोलेबल का निर्माण कर रहा है
फ्लोरेंट

13

स्टैकट्रेस हो रही है:

StackTraceElement[] ste = Thread.currentThread().getStackTrace();

मुद्रण स्टैकट्रेस (जावा 8+):

Arrays.asList(ste).forEach(System.out::println);

मुद्रण स्टैकट्रेज (JAVA 7):

StringBuilder sb = new StringBuilder();

for (StackTraceElement st : ste) {
    sb.append(st.toString() + System.lineSeparator());
}
System.out.println(sb);

12

जावा 9 में एक नया तरीका है:

public static void showTrace() {

  List<StackFrame> frames =
    StackWalker.getInstance( Option.RETAIN_CLASS_REFERENCE )
               .walk( stream  -> stream.collect( Collectors.toList() ) );

  for ( StackFrame stackFrame : frames )
    System.out.println( stackFrame );
}

दिलचस्प। :-)
djangofan

10

मेरे पास एक उपयोगिता विधि है जो स्टैकट्रेस के साथ एक स्ट्रिंग लौटाती है:

static String getStackTrace(Throwable t) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw, true);
    t.printStackTrace(pw);
    pw.flush();
    sw.flush();
    return sw.toString();
}

और बस लॉग इन करें ...

... 
catch (FileNotFoundException e) {
    logger.config(getStackTrace(e));
}

यह नेटबिन द्वारा उत्पन्न एक ऑटो जैसा दिखता है।
लेइफ ग्रुएनवोल्ड्ट

लकड़हारा एक लकड़हारा या आपके द्वारा बनाई गई एक फ़ाइल में लिखने वाला है।
डग Hauf

@Doug Hauf, लकड़हारा जावा लॉगर में निर्मित का एक संदर्भ है। सुनिश्चित करें कि आप logging.properties फ़ाइल को कॉन्फ़िगर करते हैं। इसे अपनी कक्षा की शुरुआत में इस तरह जोड़ें: निजी स्थैतिक अंतिम लकड़हारा लकड़हारा = लकड़हारा। लॉगर (Your_Class_Name.class.getName ());
साल्वाडोर वालेंसिया

1
java.util.logging.Logger#log(Level, String, Throwable)पहले से ही ऐसा करता है। यह उन चीजों को फिर से लिख रहा है जो पहले से ही जावा मानक पुस्तकालय में अनावश्यक रूप से मौजूद हैं और नए डेवलपर्स को गलत दिशा में इंगित कर रहे हैं, जो प्रलेखन से दूर है। ऐसा करके अब आपने स्टैकट्रेस को एक निश्चित तरीके से फॉर्मेट करने के लिए मजबूर किया है, जहां loggingएपीआई आपको लॉग स्टेटमेंट के प्रारूपण को गतिशील रूप से निर्दिष्ट करने की अनुमति देता है। मेरी जानकारी के लिए, log4jसमान व्यवहार भी है। पहिया को सुदृढ़ न करें क्योंकि आप चीजों को खो देते हैं जैसे कि मैंने समझाया है।
19eng में searchengine27

1
यह 2012 में भी अस्तित्व में था। दुर्भाग्यवश, आपके मामले में तिथि में कोई अंतर नहीं है। देखें [लिंक] (docs.oracle.com/javase/1.5.0/docs/api/java/util/log/Logger.html#log (java.util.logging.Level, java.lang.tring, java.lang) .Throwable)), [लिंक] (docs.oracle.com/javase/1.5.0/docs/api/java/util/logging/Logger.html#log (java.util.logging.Loggerecord)), आदि (वहां) कई कार्य है कि पारित कर रहे हैं Throwableके लिए रवाना Handlerकरने के लिए के माध्यम से रों Formatterसे अधिक मैं यहाँ सूचीबद्ध किया है जो 2012 Java7 था, में और इन कार्यों वापस दूर से अधिक समय Java7 के आसपास किया गया है का है;। इसलिए J2SE 5.0 javadocs)
searchengine27

10

अमरूद के साथ कड़ा करने के लिए:

Throwables.getStackTraceAsString(new Throwable())

8
try {
}
catch(Exception e) {
    StackTraceElement[] traceElements = e.getStackTrace();
    //...
}

या

Thread.currentThread().getStackTrace()

क्या आपका शीर्ष उदाहरण केवल आपको स्टैक ट्रेस ट्राई / कैच ब्लॉक के सापेक्ष नहीं देगा?
डैन मोनेगो जूल

1
दोनों के बीच क्या अंतर है
twlkyao

5

शायद आप यह कोशिश कर सकते हैं:

catch(Exception e)
{
    StringWriter writer = new StringWriter();
    PrintWriter pw = new PrintWriter(writer);
    e.printStackTrace(pw);
    String errorDetail = writer.toString();
}

स्ट्रिंग 'errorDetail' में स्टैकट्रेस है।


5
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();

सरणी का अंतिम तत्व स्टैक के निचले भाग का प्रतिनिधित्व करता है, जो अनुक्रम में कम से कम हाल ही में विधि मंगलाचरण है।

A StackTraceElement has getClassName(), getFileName(), getLineNumber() and getMethodName().

StackTraceElement के माध्यम से लूप करें और अपना वांछित परिणाम प्राप्त करें।

for (StackTraceElement ste : stackTraceElements ) 
{
    //do your stuff here...
}

अंतिम तत्व का उल्लेख करने के लिए धन्यवाद में सबसे हाल ही में शामिल है। काउंटर-सहज और मुझे कुछ समय बचाया।
स्पष्ट करें

.toString () सभी डेटा को एक स्ट्रिंग में अच्छी तरह से आउटपुट करेगा
व्लाद

4

मैंने ऊपर से उत्तर का उपयोग किया और स्वरूपण जोड़ा

public final class DebugUtil {

    private static final String SEPARATOR = "\n";

    private DebugUtil() {
    }

    public static String formatStackTrace(StackTraceElement[] stackTrace) {
        StringBuilder buffer = new StringBuilder();
        for (StackTraceElement element : stackTrace) {
            buffer.append(element).append(SEPARATOR);
        }
        return buffer.toString();
    }

    public static String formatCurrentStacktrace() {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        return formatStackTrace(stackTrace);
    }
}

2

यदि आप अपनी प्रक्रिया के वर्तमान कॉल स्टैक की जांच करना चाहते हैं, तो आप jstack उपयोगिता का उपयोग कर सकते हैं।

Usage:
    jstack [-l] <pid>
        (to connect to running process)
    jstack -F [-m] [-l] <pid>
        (to connect to a hung process)
    jstack [-m] [-l] <executable> <core>
        (to connect to a core file)
    jstack [-m] [-l] [server_id@]<remote server IP or hostname>
        (to connect to a remote debug server)

Options:
    -F  to force a thread dump. Use when jstack <pid> does not respond (process is hung)
    -m  to print both java and native frames (mixed mode)
    -l  long listing. Prints additional information about locks
    -h or -help to print this help message

1

यह एक पुरानी पोस्ट है, लेकिन यहाँ मेरा समाधान है:

Thread.currentThread().dumpStack();

अधिक जानकारी और अधिक विधियाँ: http://javarevisited.blogspot.fr/2013/04/how-to-get-current-stack-trace-in-java-thread.html


3
चूंकि Thread.dumpStack () स्थिर है, आपको इसे सीधे कॉल करना चाहिए।
डेविड एवेंदासोरा

2
ओपी ने संकेत दिया कि वे स्टैक ट्रेस के कोड में एक संदर्भ चाहते हैं, न कि इसे प्रिंट करने के लिए।
टेलर आर

1
जैसा कि @DavidAvendasora ने उल्लेख किया है कि आपको Thread.dumpStack()सीधे कॉल करना चाहिए क्योंकि इसकी स्थिर विधि।
एम-वाजेह

हां, java.lang.Thread.dumpStack () जावा 11 पर काम करता है
पार्क जोंगबूम

-3

System.out.println(Arrays.toString(Thread.currentThread().getStackTrace()));

यह आपको लूप के बिना स्टैक ट्रेस प्रिंट करने में मदद करेगा।


1
आपका उत्तर वही है जो मेरे द्वारा 3 महीने पहले पोस्ट किया गया था।
माइक कृंतक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.