(Origine sconosciuta) nella traccia dello stack di eccezioni

sfondo

Questa domanda è correlata a Perché String.valueOf (null) lancia una NullPointerException?

Considera il seguente frammento:

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 } } 

Come spiegato nella risposta alla domanda collegata, l’overloading del metodo di Java risolve la suddetta invocazione a String.valueOf(char[]) , che giustamente genera una NullPointerException in fase di esecuzione.

Compilato in Eclipse e javac 1.6.0_17 , questa è la traccia dello stack:

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

Si noti che la traccia dello stack sopra manca le informazioni KEY : NON ha la firma completa del metodo valueOf ! Dice solo String.valueOf(Unknown Source) !

Nella maggior parte delle situazioni che ho riscontrato, le tracce dello stack di eccezioni hanno sempre la firma completa dei metodi che sono effettivamente nella traccia dello stack, che ovviamente è molto utile per identificare immediatamente il problema e una delle ragioni principali per cui la traccia dello stack (che non serve dire che è piuttosto costoso da build) è fornito in primo luogo.

Eppure, in questo caso, la traccia dello stack non aiuta affatto . Ha fallito miseramente nell’aiutare il programmatore a identificare il problema.

Come è, posso vedere 3 modi in cui un programmatore può identificare il problema con il frammento di cui sopra:

  • Il programmatore capisce da solo che il metodo è sovraccarico e, in base alla regola della risoluzione, il sovraccarico “errato” viene invocato in questo caso
  • Il programmatore utilizza un buon IDE che gli consente di vedere rapidamente quale metodo è selezionato
    • In Eclipse, ad esempio, il passaggio del mouse sopra l’espressione sopra indica rapidamente al programmatore che lo String valueOf(char[] data) è effettivamente quello selezionato
  • Il programmatore esamina il bytecode (ugh!)

L’ultima opzione è probabilmente la meno accessibile, ma ovviamente è l’ultima risposta (un programmatore può fraintendere la regola di sovraccarico, l’IDE può essere bacato, ma i byte sempre (?) Dicono la verità su ciò che viene fatto).


Le domande

  • Perché la traccia dello stack è così poco informativa in questo caso rispetto alle firme dei metodi che sono effettivamente nella traccia dello stack?
    • Questo è dovuto al compilatore? Il runtime? Qualcos’altro?
  • In quali altri (rari?) Scenari la traccia dello stack non riesce a catturare informazioni essenziali come queste?

Questo è normalmente correlato alla mancanza di informazioni di debug. Probabilmente stai usando JRE (non JDK), che non include le informazioni di debug per le classi rt.jar. Prova a utilizzare JDK completo, otterrai le posizioni corrette nella traccia dello stack:

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

Si noti che se si utilizza la build Ant e se l’attributo debug è impostato su false nel comando javac, ciò potrebbe accadere.

ex: se hai bisogno di una corretta posizione in trace set debug = true in Ant build,

     

Ho avuto lo stesso problema, sto usando la molla e l’ apache per un’integrazione continua.

L’errore che avevo era nel file build.xml.

Il registro delle modifiche di genere con contenuti più precisi era:

build.xml con l’errore:

     

build.xml senza errori:

     

All’interno della struttura mi mancava il coraggio debug = “true”

Ho eseguito il codice in Eclipse e ho ottenuto il seguente output,

 public class Aloof { public static void main(String[] args) { String.valueOf(null); } } Exception in thread "main" java.lang.NullPointerException at java.lang.String.(String.java:177) at java.lang.String.valueOf(String.java:2840) at mysql.Aloof.main(Aloof.java:19) 

Se si include l’origine completa (da JDK), è ansible eseguire il debug sulla riga 177 in String.java

Questo accade quando non ci sono informazioni di debug (linea) nell’origine o la VM viene avvertita di buttare via tali informazioni in fase di caricamento della class. Dato che hai alcuni numeri di riga, non è l’impostazione della macchina virtuale, ma la class String informazioni di debug.

In Eclipse: Preferenze> Java> JRE installati. La voce selezionata deve avere un percorso all’interno del JDK, ad es. C: \ Programmi (x86) \ Java \ jdk1.7.0_55 \ jre.