मुझे जावा में वर्तमान स्टैक ट्रेस कैसे मिलता है , जैसे .NET में आप कैसे कर सकते हैं Environment.StackTrace
?
मैंने पाया Thread.dumpStack()
लेकिन यह वह नहीं है जो मैं चाहता हूं - मैं स्टैक ट्रेस वापस लेना चाहता हूं, इसे प्रिंट नहीं करना चाहता हूं।
मुझे जावा में वर्तमान स्टैक ट्रेस कैसे मिलता है , जैसे .NET में आप कैसे कर सकते हैं Environment.StackTrace
?
मैंने पाया Thread.dumpStack()
लेकिन यह वह नहीं है जो मैं चाहता हूं - मैं स्टैक ट्रेस वापस लेना चाहता हूं, इसे प्रिंट नहीं करना चाहता हूं।
जवाबों:
आप उपयोग कर सकते हैं Thread.currentThread().getStackTrace()
।
यह एक सरणी देता है जो StackTraceElement
किसी प्रोग्राम के वर्तमान स्टैक ट्रेस का प्रतिनिधित्व करता है।
String fullStackTrace = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e);
stackoverflow.com/a/10620951/11236
new Throwable().getStackTrace()
यह बहुत तेज़ है, क्योंकि इसे जांचने की आवश्यकता नहीं है this != Thread.currentThread()
और संभावित जेवीएम ओवरहेड्स को चाइल्ड-क्लास के माध्यम से कॉल करने की आवश्यकता है ( Exception extends Throwable
)
Thread.currentThread().getStackTrace();
ठीक है अगर आपको परवाह नहीं है कि स्टैक का पहला तत्व क्या है।
new Throwable().getStackTrace();
आपके मौजूदा तरीके के लिए एक परिभाषित स्थिति होगी, अगर यह मायने रखता है।
(new Throwable()).getStackTrace()
बहुत तेज़ी से क्रियान्वित हो रहा है (देखें बग्ससून.com
(new Exception()).getStackTrace()
तब होता है जब अनुरोधित स्टैक ट्रेस वर्तमान थ्रेड पर होता है (जो हमेशा के लिए होगाThread.currentThread().getStackTrace();
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
System.out.println(ste);
}
new Exception().printStackTrace(System.out)
जिसे मैं याद रख सकता हूं, लूप के लिए संभवतः कम ओवरहेड है, लेकिन आपको इसे केवल डिबगिंग चीज़ के रूप में उपयोग करना चाहिए ...
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) { if(ste.toString().contains("mypackages")){ System.out.println(ste); } }
Thread.currentThread().getStackTrace();
JDK1.5 के बाद से उपलब्ध है।
एक पुराने संस्करण के लिए, आप अनुप्रेषित कर सकते हैं exception.printStackTrace()
एक करने के लिए StringWriter()
:
StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
new Throwable().getStackTrace()
JDK1.4 के बाद से उपलब्ध है ...
आप उसके लिए अपाचे के कॉमन्स का उपयोग कर सकते हैं:
String fullStackTrace = org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
org.apache.commons.lang3
, पूरी लाइन है:org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
org.apache.commons.lang3
मैं शुरू में अनदेखी की है, जो आयात करने के लिए fileoffset की टिप्पणी को दोहराने के लिए - आयात के lang3
बजाय का उपयोग करता है lang
, और के getFullStackTrace
साथ बदल देता है getStackTrace
।
ExceptionUtils.getStackTrace(new Throwable())
स्टैक ट्रेस प्राप्त करने के लिए अभिव्यक्ति का उपयोग करना बहुत अच्छा है ।
एंड्रॉइड पर इसका उपयोग करने का एक आसान तरीका है:
import android.util.Log;
String stackTrace = Log.getStackTraceString(exception);
सभी थ्रेड्स का स्टैक ट्रेस प्राप्त करने के लिए आप या तो 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()
;
System.err.println(elems[i])
प्रत्येक पर करते हैं)। स्निपेट में दूसरी पंक्ति bean.
पहले गायब है , dumpAllThreads
लेकिन मुझे लगता है कि ज्यादातर लोग इसे बाहर काम कर सकते हैं।
एक अन्य समाधान (केवल 35 31 वर्ण):
new Exception().printStackTrace();
new Error().printStackTrace();
टोनी ने स्वीकार किए गए उत्तर की टिप्पणी के रूप में, वही दिया जो सबसे अच्छा उत्तर लगता है जो वास्तव में ओपी के प्रश्न का उत्तर देता है :
Arrays.toString(Thread.currentThread().getStackTrace()).replace( ',', '\n' );
... ओपी ने यह नहीं पूछा कि String
स्टैक ट्रेस से कैसे प्राप्त किया जाए Exception
। और हालांकि मैं अपाचे कॉमन्स का बहुत बड़ा प्रशंसक हूं, जब ऊपर से कुछ सरल है तो बाहर की लाइब्रेरी का उपयोग करने का कोई तार्किक कारण नहीं है।
Thread.getAllStackTraces()
जो आपको देता है Map<Thread, StackTraceElement[]>
। जब भी किसी को सुरक्षित करने की आवश्यकता होगी, हॉटस्पॉट सभी थ्रेड्स को सुरक्षित करेगा। ज़िंग दूसरे को परेशान किए बिना अलग-अलग थ्रेड्स को सुरक्षित स्थान पर ला सकता है। स्टैकट्रेस प्राप्त करने के लिए एक सुरक्षित स्थान की आवश्यकता होती है। Thread.getAllStackTraces()
सभी स्टैक के निशान हो जाते हैं और केवल एक बार सभी थ्रेड्स को रोक देता है। बेशक, आपको यह पता लगाना चाहिए कि आप वास्तव में किस मैपिंग में रुचि रखते हैं।
मेरा सुझाव है कि
Thread.dumpStack()
एक आसान तरीका है और इसका फायदा यह है कि वास्तव में एक अपवाद या फेंकने योग्य नहीं है जब कोई समस्या नहीं हो सकती है, और बिंदु के लिए काफी अधिक है।
new Exception("Stack trace").printStackTrace();
इसलिए यह वास्तव में एक थ्रोलेबल का निर्माण कर रहा है
स्टैकट्रेस हो रही है:
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);
जावा 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 );
}
मेरे पास एक उपयोगिता विधि है जो स्टैकट्रेस के साथ एक स्ट्रिंग लौटाती है:
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));
}
java.util.logging.Logger#log(Level, String, Throwable)
पहले से ही ऐसा करता है। यह उन चीजों को फिर से लिख रहा है जो पहले से ही जावा मानक पुस्तकालय में अनावश्यक रूप से मौजूद हैं और नए डेवलपर्स को गलत दिशा में इंगित कर रहे हैं, जो प्रलेखन से दूर है। ऐसा करके अब आपने स्टैकट्रेस को एक निश्चित तरीके से फॉर्मेट करने के लिए मजबूर किया है, जहां logging
एपीआई आपको लॉग स्टेटमेंट के प्रारूपण को गतिशील रूप से निर्दिष्ट करने की अनुमति देता है। मेरी जानकारी के लिए, log4j
समान व्यवहार भी है। पहिया को सुदृढ़ न करें क्योंकि आप चीजों को खो देते हैं जैसे कि मैंने समझाया है।
Throwable
के लिए रवाना Handler
करने के लिए के माध्यम से रों Formatter
से अधिक मैं यहाँ सूचीबद्ध किया है जो 2012 Java7 था, में और इन कार्यों वापस दूर से अधिक समय Java7 के आसपास किया गया है का है;। इसलिए J2SE 5.0 javadocs)
try {
}
catch(Exception e) {
StackTraceElement[] traceElements = e.getStackTrace();
//...
}
या
Thread.currentThread().getStackTrace()
शायद आप यह कोशिश कर सकते हैं:
catch(Exception e)
{
StringWriter writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
e.printStackTrace(pw);
String errorDetail = writer.toString();
}
स्ट्रिंग 'errorDetail' में स्टैकट्रेस है।
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
सरणी का अंतिम तत्व स्टैक के निचले भाग का प्रतिनिधित्व करता है, जो अनुक्रम में कम से कम हाल ही में विधि मंगलाचरण है।
A StackTraceElement has getClassName(), getFileName(), getLineNumber() and getMethodName().
StackTraceElement के माध्यम से लूप करें और अपना वांछित परिणाम प्राप्त करें।
for (StackTraceElement ste : stackTraceElements )
{
//do your stuff here...
}
मैंने ऊपर से उत्तर का उपयोग किया और स्वरूपण जोड़ा
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);
}
}
यदि आप अपनी प्रक्रिया के वर्तमान कॉल स्टैक की जांच करना चाहते हैं, तो आप 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
यह एक पुरानी पोस्ट है, लेकिन यहाँ मेरा समाधान है:
Thread.currentThread().dumpStack();
अधिक जानकारी और अधिक विधियाँ: http://javarevisited.blogspot.fr/2013/04/how-to-get-current-stack-trace-in-java-thread.html
Thread.dumpStack()
सीधे कॉल करना चाहिए क्योंकि इसकी स्थिर विधि।
System.out.println(Arrays.toString(Thread.currentThread().getStackTrace()));
यह आपको लूप के बिना स्टैक ट्रेस प्रिंट करने में मदद करेगा।