51 votes

(Source inconnue) dans la trace de pile d'exception

Arrière-plan

Cette question est liée à Pourquoi Chaîne.valueOf(null) throw un NullPointerException?

Considérons le fragment de code suivant:

public class StringValueOfNull {
    public static void main(String[] args) {
        String.valueOf(null);

        // programmer intention is to invoke valueOf(Object), but instead
        // code invokes valueOf(char[]) and throws NullPointerException
    }
}

Comme expliqué dans la réponse à la question, Java est la surcharge de méthode résout le ci-dessus invokation d' String.valueOf(char[]), ce qui se traduit légitimement en NullPointerException au moment de l'exécution.

Compilé dans Eclipse et javac 1.6.0_17, c'est la trace de la pile:

Exception in thread "main" java.lang.NullPointerException
        at java.lang.String.<init>(Unknown Source)
        at java.lang.String.valueOf(Unknown Source)
        at StringValueOfNull.main(StringValueOfNull.java:3)

Notez que la trace de la pile ci-dessus est absent de la CLÉ de l'information: il n'est PAS de disposer de l'intégralité de la signature de l' valueOf méthode! Il dit juste qu' String.valueOf(Unknown Source)!

Dans la plupart des situations que j'ai rencontrées, à l'exception des traces de pile de toujours disposer de la signature complète des méthodes qui sont réellement dans la trace de la pile, ce qui est très utile dans l'identification du problème immédiatement, et l'une des principales raisons pourquoi la trace de la pile (qui va sans dire est assez coûteux à construire) est prévue dans la première place.

Et pourtant, dans ce cas, la trace de la pile ne permet pas à tous. Il a lamentablement échoué à aider le programmeur à identifier le problème.

Comme je peux voir 3 façons qu'un programmeur peut identifier le problème avec l'extrait ci-dessus:

  • Programmeur réalise sur son propre que la méthode est surchargée, et par la résolution de la règle, le "mauvais" surcharge est appelé dans ce cas
  • Programmeur utilise une bonne IDE qui lui permet de voir rapidement la méthode qui est sélectionné
    • Dans Eclipse, par exemple, la souris-planant sur l'expression ci-dessus rapidement dit que le programmeur String valueOf(char[] data) est en effet celui qui est sélectionné
  • Programmeur examine le bytecode (pouah!)

La dernière option est probablement la moins accessible, mais, bien sûr, est la Réponse Ultime (un programmeur peut faire mal compris la surcharge de la règle, l'IDE peut être buggé, mais bytecode toujours(?) dire la vérité sur ce qui est fait).


Les questions

  • Pourquoi est-ce la trace de la pile, donc peu utile dans ce cas en ce qui concerne les signatures des méthodes qui sont réellement dans la trace de la pile?
    • Est-ce dû au compilateur? Le moteur d'exécution? Quelque chose d'autre?
  • Dans ce que d'autres (rares?) les scénarios peuvent la trace de la pile ne parviennent pas à capturer les informations essentielles comme celle-ci?

102voto

Supun Sameera Points 818

Notez que si vous utilisez Ant build et que l'attribut debug a la valeur false dans la commande javac, cela peut se produire.

ex: si vous avez besoin d'un emplacement approprié dans la trace, définissez debug = true dans Ant build,

     <javac verbose="false" srcdir="${src}" destdir="${classdir}" debug="true" includes="**/*.java">
        <classpath refid="compile.classpath" />
    </javac>
 

29voto

unbeli Points 9573

Ceci est normalement lié aux informations de débogage manquantes. Vous utilisez probablement JRE (pas JDK), qui n'inclut pas les informations de débogage pour les classes rt.jar. Essayez d’utiliser JDK complet, vous obtiendrez des emplacements appropriés dans la trace de la pile:

 Exception in thread "main" java.lang.NullPointerException
    at java.lang.String.<init>(String.java:177)
    at java.lang.String.valueOf(String.java:2840)
    at StringValueOfNull.main(StringValueOfNull.java:3)
 

6voto

jamlhet Points 26

J'ai eu le même problème, j'utilise Spring et Apache Ant pour l'intégration continue.

L'erreur que j'ai eu était dans le fichier build.xml.

Le journal de changement de genre avec un contenu plus précis était:

build.xml avec l'erreur:

     <javac srcdir="${src.home}" destdir="${work.home}/WEB-INF/classes">
        <classpath refid="compile.classpath" />
    </javac>
 

build.xml sans erreur:

     <javac srcdir="${src.home}" destdir="${work.home}/WEB-INF/classes"  debug="true">
        <classpath refid="compile.classpath" />
    </javac>
 

Au sein de la structure il me manquait le courage debug = "true"

3voto

bragboy Points 13615

J'ai couru le code dans Eclipse et j'ai eu la sortie suivante,

 public class Aloof {
    public static void main(String[] args) {
        String.valueOf(null);
    }
}

Exception in thread "main" java.lang.NullPointerException
    at java.lang.String.<init>(String.java:177)
    at java.lang.String.valueOf(String.java:2840)
    at mysql.Aloof.main(Aloof.java:19)
 

Si vous incluez le code source complet (à partir de JDK), vous pouvez réellement déboguer la ligne 177 dans String.java.

1voto

Aaron Digulla Points 143830

Cela se produit lorsqu'il n'y a aucune information de débogage (ligne) dans la source ou lorsque la machine virtuelle est invitée à la jeter au moment du chargement de la classe. Étant donné que vous avez des numéros de ligne, ce n'est pas le paramètre de la machine virtuelle mais les informations de débogage de la classe String sont manquantes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X