(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 à String.valueOf(char[])
, qui à juste titre les résultats dans un 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)
Noter que la trace de la pile ci-dessus est absent de la CLÉ de l'information: il ne PAS ont la signature complète de la valueOf
méthode! Il dit seulement 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, qui est bien sûr 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.
Est aussi, je peux voir les 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 programmeur que le
String valueOf(char[] data)
est en effet celui qui est sélectionné
- Dans Eclipse, par exemple, la souris-planant sur l'expression ci-dessus rapidement dit programmeur que le
- 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 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?
- Notez que le contenu exact d'une trace de la pile n'est pas spécifié dans la JVM spécification ou de la JLS, de sorte que les réalisateurs sont assez libre sur ce qu'ils fournissent. Aussi: mon installation fournit le fichier source et le numéro de ligne dans le stacktrace (c'est l'OpenJDK, cependant), donc je pense que ça dépend de ce que vous utilisez pour exécuter votre code (JRE vs JDK).
- Waouh je viens de réaliser que j'ai peut-être fait un fou de moi-même ici; à l'exception des traces de pile ne sont JAMAIS inclus la signature de la méthode, apparemment(?). Il ne comprend que le nom de fichier et le numéro de ligne, au mieux. Je vous jure que j'ai vu les signatures trop avant, mais peut-être que je me trompe en quelque sorte. Aurait été agréable, bien que (et devrait être facile à mettre en œuvre, puisque l'information à propos de la signature est plus disponible que le nom du fichier source et le numéro de ligne).
- y compris la totalité des signatures de méthode serait de faire des traces de pile très difficile à lire.
Vous devez vous connecter pour publier un commentaire.
C'est normalement liés au manque les informations de débogage. Vous êtes probablement à l'aide de la JRE (pas de JDK), qui n'inclut pas les informations de débogage pour rt.jar des classes. Essayez d'utiliser à plein JDK, vous obtiendrez des emplacements appropriés dans la trace de la pile:
javac
de compiler vos sources, vous pouvez activer le débogage d'infos avec-g
option de ligne de commande.-g
drapeau. Toutes sortes de IDEs et de construire des outils (par exemple. mvn, ant, gradle) disposent de différents moyens pour activer ou désactiver les informations de débogage.Notez que si vous utilisez Ant et si le débogage attribut défini sur false dans la commande javac cela pourrait se produire.
ex : si vous avez besoin d'un bon emplacement en oligo-ensemble debug = true en Ant,
J'ai eu le même problème, je suis en utilisant printemps et apache ant pour l'intégration continue.
L'erreur que j'ai eu était dans l'build.xml fichier.
Le changement de genre de journal avec un contenu plus précis a été:
build.xml avec l'erreur:
build.xml sans erreur:
Au sein de la structure, je n'aurais pas le courage debug = "true"
J'ai couru le code dans Eclipse et j'ai obtenu le résultat suivant,
Si vous incluez la source (à partir de JDK), vous pouvez réellement de débogage pour la ligne 177 String.java
Ce qui se passe quand il n'y a pas de debug (ligne) de l'information à la source ou à la machine virtuelle est dit de jeter cette information à la classe de temps de chargement. Puisque vous avez quelques numéros de ligne, ce n'est pas la VM, mais la classe
String
manque les informations de débogage.Dans Eclipse: Préférences > Java > Installé Jre. L'objet d'une entrée doit avoir un chemin à l'intérieur de la JDK, par exemple C:\Program Files (x86)\Java\jdk1.7.0_55\jre.