Sepuluh Tips Menggunakan Java Stack Traces

Sebagian besar pengembang Java agak terbiasa dengan pelacakan tumpukan Java dan cara membaca serta menganalisis pelacakan tumpukan. Namun, untuk pengembang Java pemula, ada beberapa area pelacakan tumpukan yang mungkin sedikit membingungkan. Dalam posting ini, saya melihat beberapa tip untuk membaca jejak tumpukan Java dan merespons dengan tepat berdasarkan apa yang dilaporkan pelacakan tumpukan.

1. Jejak Stack Bukan Hanya untuk Kesalahan dan Pengecualian

Kesalahpahaman umum di antara pengembang Java baru dan di antara orang-orang yang tidak terbiasa dengan Java adalah bahwa jejak tumpukan menunjukkan pengecualian. Meskipun pelacakan tumpukan umumnya dikaitkan dengan pengecualian yang ditemukan, pengembang Java dapat mengakses pelacakan tumpukan kapan saja tanpa perlu pengecualian. Salah satu cara untuk melakukannya adalah dengan memanggil Thread.currentThread (). GetStackTrace () untuk mengakses array StackTraceElements. Saya menunjukkan ini sebelumnya di posting saya The StackTraceElement yang Mengejutkan Sederhana. Akan berguna untuk mengakses pelacakan tumpukan bahkan di luar situasi luar biasa untuk memahami bagaimana kode mengalir. Ini StackTraceElementjuga berguna karena memungkinkan akses granular ke potongan jejak tumpukan.

Penggunaan pelacakan tumpukan non-error lainnya terkait dengan kemampuan Java untuk memberikan detail tentang proses yang berjalan saat diminta dari baris perintah. Ini dijelaskan lebih detail di bagian selanjutnya dari posting ini.

2. Stack Trace Disajikan dari Terbaru ke Terlama

Salah satu konsep terpenting untuk memahami pelacakan tumpukan dengan benar adalah dengan mengenali bahwa ia mencantumkan jalur eksekusi dalam urutan kronologis terbalik dari operasi terbaru hingga operasi paling awal. Dalam banyak hal, menganalisis pelacakan tumpukan dengan benar seperti menganalisis kesalahan kompiler dengan benar: urutan itu penting. Dengan kesalahan kompilator, biasanya yang terbaik adalah menganalisis kesalahan kompilator pertama karena itu sering menyebabkan kesalahan kompilator berikutnya. Demikian pula, dengan pelacakan tumpukan, seringkali paling berguna untuk memulai dengan operasi terbaru dan bekerja mundur seperlunya hingga pelacakan tumpukan untuk melihat bagaimana kondisi tersebut dicapai. Untuk beberapa pengecualian, seperti beberapa NullPointerExceptions, analisis baris tempat terjadinya pengecualian dapat menjadi semua yang diperlukan untuk memahami apa yang salah.

3. Pahami Pengecualian yang Dirantai

Pengamatan penting lainnya adalah bahwa jejak tumpukan yang menunjukkan pengecualian sering kali menyertakan pengecualian berantai. Hal ini penting untuk dipahami karena sering kali salah satu pengecualian mendasar yang mendasari pengecualian yang terakhir ditemui adalah penyebab sebenarnya yang harus ditangani dengan tepat. Sama seperti menangani kesalahan kompilator terakhir yang dilaporkan sebelum menangani kesalahan yang dilaporkan pertama kali merupakan ide yang bagus, juga penting untuk menganalisis pengecualian yang mendasarinya. Fasilitas pengecualian berantai ini merupakan tambahan yang disambut baik untuk Java 1.4 karena memungkinkan pengembang Java untuk lebih mudah menentukan penyebab sebenarnya dari berbagai pengecualian.Seringkali pengecualian yang paling penting untuk diperhatikan dalam daftar panjang pengecualian berantai adalah pengecualian pertama yang terjadi (biasanya tercantum di bagian paling bawah dari jejak tumpukan yang panjang dan sering didahului dengan notasi "Disebabkan oleh").

4. Kompilasi dengan Debug Diaktifkan

Saat pelacakan tumpukan digunakan untuk menentukan mengapa pengecualian terjadi atau apa aliran kode itu, akan sangat berguna untuk memiliki akses ke nomor baris dari setiap langkah yang dijalankan yang dicakup oleh pelacakan tumpukan. Secara default di Java SE 6 javac Oracle, nomor baris dan nama file sumber disertakan dalam pelacakan tumpukan. Sangat mudah untuk menonaktifkan pencetakan informasi ini dengan menyetel -g:noneopsi javac , tetapi ini biasanya bukan ide yang baik selama pengembangan. Sebagian besar alat build juga memudahkan untuk mengaktifkan debugging dan mengontrol level debugging. Ant, misalnya, menyediakan debugatribut untuk tugas javac yang bisa disetel trueuntuk mengaktifkan debugging.

5. Mencatat dan Menangani Jejak Tumpukan Pengecualian

Karena pelacakan tumpukan Java sangat sering dikaitkan dengan pengecualian, sangat berguna untuk mengetahui cara melaporkannya dengan benar. Untungnya, dua framework logging Java yang paling populer, java.util.logging dan log4j, menyediakan metode praktis untuk pengecualian logging yang akan menangani informasi pelacakan tumpukan secara otomatis. Misalnya, java.util.loggingmenyediakan versi Logger.log yang kelebihan beban yang menerima Throwable dan log4j menyediakan beberapa metode kelebihan beban pada kelas Logger yang memungkinkan Throwables untuk dicatat dengan pesan log normal.

Terkadang perlu atau setidaknya berguna untuk mengakses pelacakan tumpukan dalam situasi kode selain logging. Salah satu cara untuk melakukannya adalah dengan menggunakan Throwable.getStackTrace () yang mengembalikan larik StackTraceElements. Pendekatan lain adalah menggunakan salah satu versi Throwable.getStackTrace () yang kelebihan beban yang tidak hanya mencetak pelacakan tumpukan ke kesalahan standar. Kedua metode kelebihan beban ini memungkinkan akses ke pelacakan tumpukan pengecualian melalui PrintStream atau PrintWriter. Dua cuplikan kode berikutnya menunjukkan mengekstraksi String dari Throwablepenggunaan PrintWriterdan PrintStreammasing - masing.

Mengekstrak String dari Throwable Via PrintWriter

/** * Provides a String representation of the provided Throwable's stack trace * that is extracted via PrintWriter. * * @param throwable Throwable/Exception from which stack trace is to be * extracted. * @return String with provided Throwable's stack trace. */ public static String accessExceptionStackTraceViaPrintWriter(final Throwable throwable) { final Writer writer = new StringWriter(); final PrintWriter printWriter = new PrintWriter(writer); throwable.printStackTrace(printWriter); return writer.toString(); } 

Mengekstrak String dari Throwable Via PrintStream

/** * Provides a String representation of the provided Throwable's stack trace * that is extracted via PrintStream. * * @param throwable Throwable/Exception from which stack trace is to be * extracted. * @return String with provided Throwable's stack trace. */ public static String accessExceptionStackTraceViaPrintStream(final Throwable throwable) { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final PrintStream printStream = new PrintStream(baos); throwable.printStackTrace(printStream); String exceptionStr = ""; try { exceptionStr = baos.toString("UTF-8"); } catch(Exception ex) { exceptionStr = "Unavailable"; } return exceptionStr; } 

6. Beberapa Pendekatan untuk Menghasilkan / Mengakses Stack Traces

Java mendukung beberapa pendekatan untuk mengakses pelacakan tumpukan. Beberapa di antaranya diuraikan di An Introduction to Java Stack Traces dan saya sudah membahas beberapa di sini. Seperti yang dijelaskan di Tip # 1, pelacakan tumpukan dari eksekusi saat ini dapat diambil dari utas saat ini. Tip tepat sebelumnya, Tip # 5, menutupi ekstraksi jejak tumpukan dari pengecualian / kesalahan (Dapat dilempar).

Ada kalanya berguna untuk melihat apa yang dilakukan thread saat ini dan thread lain. Java mendukung ini dengan menerima sinyal dan merespons dengan menampilkan detail terkait. Penanganan sinyal bisa sedikit berbeda di semua platform, jadi ada baiknya mempelajari cara mengirim sinyal dari platform yang digunakan untuk aplikasi Java seseorang. Dokumentasi peluncur java Sun / Oracle memberikan detail yang signifikan tentang penanganan sinyal JVM di bagian yang menjelaskan opsi -Xrs (-X menunjukkan opsi non-standar). Selain menjelaskan cara menggunakan -Xrsuntuk mematikan JVM yang merespons sinyal yang diterima, dokumentasi ini juga memberikan detail lebih lanjut mengenai penanganan JVM terhadap sinyal SIGQUIT, SIGHUP, SIGINT, dan SIGTERM.

Dengan asumsi bahwa -Xrsopsi ini tidak digunakan, menggunakan CTRL-BREAK di jendela konsol Windows tempat aplikasi Java dimulai akan mengarah ke thread dump dari utas saat ini yang sedang ditampilkan. Ini ditunjukkan dalam cuplikan layar berikut saat menjalankan aplikasi Java dan melihat thread dump di Windows PowerShell.

Untuk sistem Linux dan Unix, sinyal yang sama dikirim secara berbeda. Ini dapat dikirim dengan CTRL- \ (tombol CTRL diikuti dengan garis miring) atau dengan perintah kill -QUIT pid(di mana 'pid' adalah ID proses). Alat utilitas jstack juga mudah digunakan untuk melihat utas yang terkait dengan proses tertentu (sering kali untuk pengenal proses yang ditentukan).

IDE Java seperti Eclipse dan NetBeans juga menyediakan mekanisme untuk melihat thread dump dan pelacakan tumpukan saat ini.

7. Pahami Konvensi Penamaan Antarmuka / Kelas Java

Saat membaca dan menganalisis pelacakan tumpukan Java, sebaiknya pahami konvensi penamaan antarmuka dan kelas. Satu sumber informasi tentang konvensi ini disediakan dalam dokumentasi Javadoc untuk Class.getName (). Dokumentasi ini menjelaskan konvensi penamaan untuk kelas, antarmuka, array, primitif, dan sebagainya. Ini menyatakan bahwa array ditandai dengan penjepit persegi: [. Ini juga menjelaskan bahwa elemen array ditandai dengan berbagai huruf tergantung pada tipenya: Luntuk kelas dan antarmuka, Zuntuk boolean, Buntuk byte, Cuntuk char, Duntuk double, Funtuk float, Iuntuk int, Juntuk long, dan Suntukshort. Mengetahui apa yang diwakili oleh huruf-huruf ini dalam representasi larik dapat mempermudah untuk membaca informasi mengenai hal ini dalam pelacakan tumpukan. Seperti yang saya bahas di posting blog Heap Dump and Analysis with VisualVM, konvensi penamaan yang sama ini juga dijelaskan dalam spesifikasi JVM untuk format file .class.

Konvensi penamaan dalam pelacakan tumpukan dapat bergantung pada implementasi JVM, jadi penting untuk mempelajari apa konvensi penamaan untuk JVM tertentu yang digunakan.

8. Kenali Metode Sintetis dan Jembatan

In many stack traces, it is fairly obvious which methods are being successively invoked by tracing through the stack trace.  Sometimes, however, there can be unrecognized methods. These might be from injected aspects or might be compiler-generated methods such as synthetic and bridge methods. I discussed synthetic methods in greater detail in my blog post Java's Synthetic Methods. As I stated in that post, synthetic methods are created by the compiler and usually have, in Sun's/Oracle's JVM, names such as access$100 and access$200.

9. Dude, Where's My Stack Trace?

Stack traces can be extremely useful in debugging and understanding how an application works, but they are obviously less than effective if not readily available. As described above, some Java products (such as the logging frameworks) make logging of stack traces easier. Other products log stack traces or write out their own stack traces to product-specific directories or logs. Therefore, it's important when using a new framework, tool, library, or IDE to learn where it writes its logs and stack traces. This tip also covers other essential steps such as configuring loggers appropriately to write to the appropriate locations.

10. Magnify the Power of Stack Traces with Tooling

The majority of this post has focused on reading and manually analyzing stack traces. Tools are now available that can make use of stack traces and make use of stack traces much more efficient. Eclipse's Stacktrace Console is a good example of what a Java IDE can do to make use of stack traces easier. Stack traces can be pasted into this tool and then portions of the stack trace can be clicked on to be taken directly to that class and method. NetBeans offers similar tooling features that support easier access of stack traces to the underlying classes and methods displayed in the stack trace.  Likewise, these IDEs also support generating/displaying thread dumps.

There are numerous other useful tools available in the Java ecosystem for more efficient use of Java stack traces and dumps. These include VisualVM (see my post Thread Analysis with VisualVM), jstack, and adaptj's StackTrace.

Another "tool" that is useful in conjunction with thread analysis is the powerful search engine. Although I agree that there is merit to not going right to the search engine for every problem, I have also been the beneficiary more times than I can recall of others' insight and experiences in resolving especially difficult problems. This is why I have written before that more software developers should write blogs.  Search engines make it much easier to find a description of a potential fix to some nasty problems. It is often the stack trace that provides the best clues for finding the appropriate matches via search engines such as Google, Yahoo!, and Bing. Stack trace excerpts are often found in forum threads and blog posts that either directly address the issue or provide enough information to help think through what related condition might be causing the issue.

Kesimpulan

Pelacakan tumpukan sederhana adalah salah satu alat pengembang Java yang paling kuat. Ini sangat kuat dalam men-debug dan menganalisis perangkat lunak yang ada, tetapi bahkan dapat berguna dalam pengembangan perangkat lunak. Dalam posting ini saya telah mencoba menguraikan beberapa teknik sederhana untuk mendapatkan nilai maksimal dari jejak tumpukan ini.

Posting Asli Tersedia di //marxsoftware.blogspot.com/

.

Artikel ini, "Sepuluh Tips Menggunakan Java Stack Traces", pertama kali diterbitkan oleh JavaWorld.