.NET'te nasıl yapabileceğiniz gibi , geçerli yığın izlemesini Java'da nasıl edinebilirim Environment.StackTrace
?
Buldum Thread.dumpStack()
ama istediğim bu değil - Yığın izini geri almak istiyorum, yazdırmamak istiyorum.
.NET'te nasıl yapabileceğiniz gibi , geçerli yığın izlemesini Java'da nasıl edinebilirim Environment.StackTrace
?
Buldum Thread.dumpStack()
ama istediğim bu değil - Yığın izini geri almak istiyorum, yazdırmamak istiyorum.
Yanıtlar:
Kullanabilirsiniz Thread.currentThread().getStackTrace()
.
Bu StackTraceElement
, bir programın geçerli yığın izlemesini temsil eden s dizisini döndürür .
String fullStackTrace = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e);
stackoverflow.com/a/10620951/11236
new Throwable().getStackTrace()
çok daha hızlıdır, çünkü this != Thread.currentThread()
çocuk sınıfı ( Exception extends Throwable
) aracılığıyla çağrılma potansiyel JVM genel giderlerini kontrol etmek ve atlamak zorunda değildir
Thread.currentThread().getStackTrace();
yığının ilk öğesinin ne olduğunu umursamıyorsanız iyi olur.
new Throwable().getStackTrace();
geçerli olması durumunda geçerli yönteminiz için tanımlanmış bir konuma sahip olacaktır.
(new Throwable()).getStackTrace()
daha hızlı yürütülüyor (bkz. bugs.sun.com/bugdatabase/view_bug.do?bug_id=6375302 )
(new Exception()).getStackTrace()
, istenen yığın izinin geçerli iş parçacığında olduğu zaman olduğu gibi görünüyor (her zaman böyle olacakThread.currentThread().getStackTrace();
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
System.out.println(ste);
}
new Exception().printStackTrace(System.out)
hatırlayabildiğim için, for döngüsünün muhtemelen daha az yükü vardır, ancak bunu yine de sadece hata ayıklama şey olarak kullanmalısınız ...
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) { if(ste.toString().contains("mypackages")){ System.out.println(ste); } }
Thread.currentThread().getStackTrace();
JDK 1.5'ten beri kullanılabilir.
Eski bir sürüm için, sen yönlendirebilirsiniz exception.printStackTrace()
a StringWriter()
:
StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
new Throwable().getStackTrace()
JDK 1.4'ten beri kullanılabilir…
Bunun için Apache'nin müştereklerini kullanabilirsiniz:
String fullStackTrace = org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
org.apache.commons.lang3
için tam çizgi:org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
org.apache.commons.lang3
ithalat kullanımları - Başlangıçta gözden kaçan, hangi lang3
yerine lang
ve cümledeki getFullStackTrace
ile getStackTrace
.
ExceptionUtils.getStackTrace(new Throwable())
, yığın izlemesi elde etmek için ifadeyi kullanmak harika olur .
Android'de bunu kullanmanın çok daha kolay bir yolu var:
import android.util.Log;
String stackTrace = Log.getStackTraceString(exception);
Tüm iş parçacıklarının yığın izlemesini almak için jstack yardımcı programı JConsole'yi kullanabilir veya bir kill-quit sinyali gönderebilirsiniz (Posix işletim sisteminde).
Ancak, bunu programlı olarak yapmak istiyorsanız ThreadMXBean'ı kullanmayı deneyebilirsiniz:
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
ThreadInfo[] infos = bean.dumpAllThreads(true, true);
for (ThreadInfo info : infos) {
StackTraceElement[] elems = info.getStackTrace();
// Print out elements, etc.
}
Belirtildiği gibi, sadece geçerli iş parçacığının yığın izini istiyorsanız çok daha kolay - Sadece kullanın Thread.currentThread().getStackTrace()
;
System.err.println(elems[i])
her birini yaparsanız ). Snippet'teki ikinci satır daha bean.
önce eksik dumpAllThreads
ama sanırım çoğu insan bunu halledebilir.
Başka bir çözüm (sadece 35 31 karakter):
new Exception().printStackTrace();
new Error().printStackTrace();
Tony, kabul edilen cevaba bir yorum olarak , OP'nin sorusuna gerçekten cevap veren en iyi cevap olarak görünen şeyi verdi :
Arrays.toString(Thread.currentThread().getStackTrace()).replace( ',', '\n' );
... OP vermedi DEĞİL bir nasıl sormak String
bir yığın iziyle dan Exception
. Ve Apache Commons'ın büyük bir hayranı olmama rağmen, yukarıdaki kadar basit bir şey olduğunda, bir dış kütüphaneyi kullanmak için mantıklı bir neden yoktur.
Thread.getAllStackTraces()
size a Map<Thread, StackTraceElement[]>
. Hotspot, herhangi bir konuya ihtiyaç duyduğunda tüm evreleri işaretler. Zing, bireysel iplikleri diğerini rahatsız etmeden bir güvenli noktaya getirebilir. Yığın izleme almak için bir güvenlik noktası gerekir. Thread.getAllStackTraces()
tüm yığın izlerini alır ve tüm iş parçacıklarını yalnızca bir kez durdurur. Tabii ki, hangi haritalamayla gerçekten ilgilendiğinizi öğrenmelisiniz.
Şunu öneririm
Thread.dumpStack()
daha kolay bir yoldur ve hiç bir sorun olmadığında gerçekte bir istisna veya atılabilir yapılamama avantajına sahiptir ve bu konuya göre daha fazladır.
new Exception("Stack trace").printStackTrace();
bu yüzden aslında bir Atılabilir inşa ediyor
Yığın izleme alma:
StackTraceElement[] ste = Thread.currentThread().getStackTrace();
Yazdırma yığını izi (JAVA 8+):
Arrays.asList(ste).forEach(System.out::println);
Yazdırma yığını (JAVA 7):
StringBuilder sb = new StringBuilder();
for (StackTraceElement st : ste) {
sb.append(st.toString() + System.lineSeparator());
}
System.out.println(sb);
Java 9'da yeni bir yol var:
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 );
}
Stacktrace ile bir dize döndüren bir yardımcı program yöntemi var:
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();
}
Ve sadece logit ...
...
catch (FileNotFoundException e) {
logger.config(getStackTrace(e));
}
java.util.logging.Logger#log(Level, String, Throwable)
zaten bunu yapıyor. Bu, Java standart kitaplığında zaten var olan şeyleri gereksiz yere yeniden yazmak ve yeni geliştiricileri, dokümantasyondan uzak olan yanlış yönde gösteriyor. Bunu yaparak, Stacktrace'ı belirli bir şekilde biçimlendirmeye zorladınız, burada logging
API günlük deyiminin formatını belirttiğiniz gibi dinamik olarak değiştirmenize izin verir. Bildiğim kadarıyla log4j
da benzer davranışlar var. Tekerleği yeniden icat etme çünkü açıkladığım gibi şeyleri kaybediyorsun.
Throwable
için kapalı Handler
kadar s Formatter
daha burada listeledik daha Java7 oldu 2012 yılında s Ve bu işlevler çok daha uzun Java7 civarında olmuştur daha eskiye;. dolayısıyla J2SE 5.0 javadocs)
try {
}
catch(Exception e) {
StackTraceElement[] traceElements = e.getStackTrace();
//...
}
veya
Thread.currentThread().getStackTrace()
Belki bunu deneyebilirsiniz:
catch(Exception e)
{
StringWriter writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
e.printStackTrace(pw);
String errorDetail = writer.toString();
}
'ErrorDetail' dizesi yığın izini içerir.
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
Dizinin son öğesi, dizideki en yeni yöntem çağırma olan yığının altını temsil eder.
A StackTraceElement has getClassName(), getFileName(), getLineNumber() and getMethodName().
StackTraceElement arasında geçiş yapın ve istediğiniz sonucu alın.
for (StackTraceElement ste : stackTraceElements )
{
//do your stuff here...
}
Yukarıdaki cevapları kullandım ve biçimlendirme ekledim
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);
}
}
İşleminizin geçerli çağrı yığınını kontrol etmek istiyorsanız jstack yardımcı programını kullanabilirsiniz.
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
Bu eski bir gönderi, ama işte benim çözümüm:
Thread.currentThread().dumpStack();
Daha fazla bilgi ve daha fazla yöntem var: http://javarevisited.blogspot.fr/2013/04/how-to-get-current-stack-trace-in-java-thread.html
Thread.dumpStack()
statik yöntemi nedeniyle doğrudan aramalısınız .
System.out.println(Arrays.toString(Thread.currentThread().getStackTrace()));
Bu, yığın izlemesini döngü olmadan yazdırmanıza yardımcı olacaktır.