StackTrace

Pour afficher dans les fichiers de traces les appels des méthodes, à la manière des messages d’erreurs, il existe plusieurs solutions :

  • les méthodes de la classe java.lang.Throwable,

  • les méthodes de la classe java.lang.Thread,

  • les outils externes.

Classe Throwable

En cas d’erreur ou d’exception, on dispose d’une instance de Throwable, sur laquelle on peut appeler les méthodes printStackTrace() et getStackTrace().

Sortie directe

La méthode printStackTrace() envoie directement la pile d’appel de méthodes dans la sortie d’erreur (System.err), sans passer par la case Log4J. Cela ne permet pas de gérer convenablement les sorties de traces, voire cela pourrait égarer certaines traces ! La méthode printStackTrace() est donc généralement déconseillées. Cela peut d’ailleurs être une bonne idée de modifier le template d’IDE pour la commande "surround with try catch block".

On préfère passer l’objet Throwable aux méthodes warn ou error de log4j ; celles-ci envoie la trace des appels dans tous les appenders paramétrés.

Chaîne d’appel

La méthode getStackTrace() permet de récupérer tous les éléments de trace, sous forme de tableau de StackTraceElement, et de les gérer manuellement, et plus intelligemment.

Il est aussi possible d’utiliser la méthode printStackTrace() avec un PrintStream ou un PrintWriter en paramètre. Cela permet d’envoyer la pile dans un sortie spécifique ou de la récupérer sous forme de chaîne de caractères :

public class ThrowableUtil {
    public static String getStackTraceAsString (Throwable throwable) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        throwable.printStackTrace(pw);
        return sw.getBuffer().toString();
    }
}

Si vous utilisez déjà Apache Commons Lang, cette méthode y existe déjà, dans la classe ExceptionUtils.

String stacktrace = ExceptionUtils.getStackTrace(e);

Classe Thread

La classe Thread permet de récupérer les mêmes informations, mais en fonctionnement normal, sans Throwable. Les méthodes équivalentes existent : Thread.dumpStack() et Thread.currentThread().getStackTrack(). Il existe une méthode qui fonctionne sur tous les threads : Thread.getAllStackTraces().

Les mêmes remarques s’imposent pour dumpStack() : les traces sortent directement dans la sortie standard (System.out), sans possibilité de les gérer. Les méthodes getStackTrack() et getAllStackTrack() sont disponibles depuis le JDK 5.

Outils externes

JConsole fournit un moyen graphique de parcourir l’ensemble des threads, idem pour VisualVM et Mission Control. jstack le fait en ligne de commande. Avec un client JMX, on peut aussi exploiter les informations fournies par le MBean java.lang:Threading.