NullPointerException en Java sans Stactrace

j'ai eu des instances de notre code Java attraper un NullPointerException , mais quand j'essaie de log la chaîne de stockage (qui se termine essentiellement par appeler Throwable.printStackTrace() ), tout ce que je reçois est:

java.lang.NullPointerException

quelqu'un d'autre A rencontré ce? J'ai essayé de googler pour "java null pointer empty stack trace" mais je n'ai rien trouvé de tel.

248
demandé sur ДМИТРИЙ МАЛИКОВ 2010-03-09 21:23:53

10 réponses

vous utilisez probablement le Sun JVM, qui effectue beaucoup d'optimisation. Pour récupérer les traces de la pile, vous devez passer l'option -XX:-OmitStackTraceInFastThrow à la JVM.

JVMs OpenJDK modernes (1,8 et plus?) semblent accepter le -XX:-OmitStackTraceInFastThrow drapeau (et ont stack-trace d'optimisation activée par défaut).

284
répondu Roland Illig 2018-06-06 03:19:16

comme vous l'avez mentionné dans un commentaire, vous utilisez log4j. J'ai découvert (par inadvertance) un endroit où j'avais écrit

LOG.error(exc);

au lieu du "151930920 typique"

LOG.error("Some informative message", e);

par paresse ou peut-être ne pas y penser. Ce qui est regrettable, c'est qu'il ne se comporte pas comme prévu. L'API logger prend en fait Object comme premier argument, pas une chaîne de caractères - et appelle ensuite toString() sur l'argument. Ainsi, au lieu de en obtenant la jolie trace de pile, il imprime juste le toString - qui dans le cas de NPE est assez inutile.

C'est peut-être ce que vous vivez?

52
répondu Steven Schlansker 2010-03-09 18:50:05

Nous avons vu ce même comportement dans le passé. Il s'est avéré que, pour une raison folle, si une NullPointerException se produisait au même endroit dans le code plusieurs fois, après un certain temps en utilisant Log.error(String, Throwable) cesserait d'inclure des traces de pile complète.

Essayez de regarder plus loin dans votre journal. Vous pouvez trouver le coupable.

EDIT: ce bug semble pertinent, mais il a été corrigé Il y a si longtemps probablement pas la cause.

21
répondu Matt Solnit 2010-03-10 00:54:27

Voici une explication : Hotspot fait des exceptions pour perdre leurs traces de cheminée dans la production – et le fix

Je l'ai testé sur Mac OS X

  • version java "1.6.0_26"
  • Java(TM) SE Runtime Environment (build 1.6.0_26-b03-383-11A511)
  • Java HotSpot (TM) 64-Bit Server VM (build 20.1-b02-383, mixed mode)

    Object string = "abcd";
    int i = 0;
    while (i < 12289) {
        i++;
        try {
            Integer a = (Integer) string;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

pour ce fragment de code, 12288 itérations (+fréquence?) semble être la limite où JVM a décidé de recourir à l'exception préallouée...

17
répondu Benoît Guérout 2011-10-14 21:37:14

exception.toString ne vous donne pas le Stactrace, il retourne seulement

une brève description de ce lancer. Le résultat est la concaténation de:

* the name of the class of this object
* ": " (a colon and a space)
* the result of invoking this object's getLocalizedMessage() method

utilisez exception.printStackTrace au lieu de sortir le StackTrace.

10
répondu Peter Lang 2010-03-09 18:30:59

suggestion alternative - si vous utilisez Eclipse, vous pouvez définir un point de rupture sur NullPointerException lui-même (dans la perspective de débogage, allez à l'onglet "points de rupture" et cliquez sur la petite icône qui a un ! en)

Cochez à la fois les options" pris "et" non pris " - maintenant, lorsque vous activez le NPE, vous cassez immédiatement et vous pouvez alors passer à travers et voir comment exactement il est manipulé et pourquoi vous ne recevez pas une trace de pile.

4
répondu Steven Schlansker 2010-03-09 20:14:04

toString() renvoie uniquement le nom de l'exception et le message Facultatif. Je suggère d'appeler

exception.printStackTrace()

pour vider le message, ou si vous avez besoin des détails sanglants:

 StackTraceElement[] trace = exception.getStackTrace()
1
répondu Sheldon Young 2010-03-09 18:27:44

(votre question n'est toujours pas claire si votre code appelle printStackTrace() ou si cela est fait par un gestionnaire de journalisation.)

voici quelques explications possibles sur ce qui pourrait se passer:

  • L'enregistreur / gestionnaire utilisé a été configuré pour ne produire que la chaîne de messages de l'exception, et non une trace complète de la pile.

  • votre demande (ou un tiers library) enregistre l'exception en utilisant LOG.error(ex); plutôt que la forme à 2 arguments de (par exemple) la méthode Logger log4j.

  • le message vient d'un endroit différent de celui où vous pensez qu'il est; par exemple, il vient en fait d'une méthode de bibliothèque tierce partie, ou de quelques trucs aléatoires laissés par des tentatives précédentes de débogage.

  • l'exception qui est journalisée a surchargé certaines méthodes pour obscurcir le stactrace. Si c'est le cas, l'exception ne sera pas une véritable NullPointerException, mais sera un sous-type personnalisé de NPE ou même une exception non liée.

je pense que la dernière explication possible est assez peu probable, mais les gens envisagent au moins de faire ce genre de chose pour" empêcher " la rétroingénierie. Bien sûr, il ne réussit vraiment à rendre la vie difficile pour les développeurs honnêtes.

1
répondu Stephen C 2010-03-09 22:51:29

cela affichera L'Exception, n'utilisez que pour déboguer vous devriez mieux gérer vos exceptions.

import java.io.PrintWriter;
import java.io.StringWriter;
    public 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();
    }
0
répondu Michael D. Irizarry 2010-03-09 18:31:09

lorsque vous utilisez AspectJ dans votre projet, il peut arriver qu'un aspect cache sa partie de la trace de la pile. Par exemple, aujourd'hui j'ai eu:

java.lang.NullPointerException:
  at com.company.product.MyTest.test(MyTest.java:37)

cette trace de pile a été imprimée lors de l'exécution du test via le surefire de Maven.

par contre, lors de l'exécution du test dans IntelliJ, une trace différente de pile a été imprimée:

java.lang.NullPointerException
  at com.company.product.library.ArgumentChecker.nonNull(ArgumentChecker.java:67)
  at ...
  at com.company.product.aspects.CheckArgumentsAspect.wrap(CheckArgumentsAspect.java:82)
  at ...
  at com.company.product.MyTest.test(MyTest.java:37)
0
répondu Roland Illig 2017-06-07 13:16:59