Che cos'è una traccia dello stack e come posso utilizzarla per eseguire il debug degli errori dell'applicazione?


643

A volte quando eseguo la mia applicazione mi dà un errore che assomiglia a:

Exception in thread "main" java.lang.NullPointerException
        at com.example.myproject.Book.getTitle(Book.java:16)
        at com.example.myproject.Author.getBookTitles(Author.java:25)
        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

Le persone lo hanno definito "traccia stack". Che cos'è una traccia dello stack? Cosa può dirmi dell'errore che sta accadendo nel mio programma?


A proposito di questa domanda - abbastanza spesso vedo sorgere una domanda in cui un programmatore inesperto "sta ottenendo un errore" e semplicemente incollano la loro traccia di stack e alcuni blocchi casuali di codice senza capire cos'è la traccia di stack o come possono usarla. Questa domanda è intesa come riferimento per i programmatori principianti che potrebbero aver bisogno di aiuto per comprendere il valore di una traccia dello stack.


25
Inoltre, se una riga stacktrace non contiene il nome file e un numero di riga, la classe per quella riga non è stata compilata con le informazioni di debug.
Thorbjørn Ravn Andersen,

Risposte:


590

In termini semplici, una traccia dello stack è un elenco delle chiamate del metodo che l'applicazione era nel mezzo di quando è stata generata un'eccezione.

Esempio semplice

Con l'esempio fornito nella domanda, possiamo determinare esattamente dove è stata generata l'eccezione nell'applicazione. Diamo un'occhiata alla traccia dello stack:

Exception in thread "main" java.lang.NullPointerException
        at com.example.myproject.Book.getTitle(Book.java:16)
        at com.example.myproject.Author.getBookTitles(Author.java:25)
        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

Questa è una traccia dello stack molto semplice. Se iniziamo all'inizio dell'elenco di "at ...", possiamo dire dove si è verificato il nostro errore. Quello che stiamo cercando è la chiamata di metodo più in alto che fa parte della nostra applicazione. In questo caso, è:

at com.example.myproject.Book.getTitle(Book.java:16)

Per eseguire il debug, possiamo aprirci Book.javae guardare la linea 16, che è:

15   public String getTitle() {
16      System.out.println(title.toString());
17      return title;
18   }

Ciò indicherebbe che qualcosa (probabilmente title) è nullnel codice sopra.

Esempio con una catena di eccezioni

A volte le applicazioni cattureranno un'eccezione e la rilasceranno come causa di un'altra eccezione. Questo in genere sembra:

34   public void getBookIds(int id) {
35      try {
36         book.getId(id);    // this method it throws a NullPointerException on line 22
37      } catch (NullPointerException e) {
38         throw new IllegalStateException("A book has a null property", e)
39      }
40   }

Questo potrebbe darti una traccia dello stack che assomiglia a:

Exception in thread "main" java.lang.IllegalStateException: A book has a null property
        at com.example.myproject.Author.getBookIds(Author.java:38)
        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)
Caused by: java.lang.NullPointerException
        at com.example.myproject.Book.getId(Book.java:22)
        at com.example.myproject.Author.getBookIds(Author.java:36)
        ... 1 more

Ciò che differisce in questo è il "Causato da". A volte le eccezioni avranno più sezioni "Causate da". Per questi, in genere si desidera trovare la "causa principale", che sarà una delle sezioni "Causate da" più basse nella traccia dello stack. Nel nostro caso, è:

Caused by: java.lang.NullPointerException <-- root cause
        at com.example.myproject.Book.getId(Book.java:22) <-- important line

Ancora una volta, con questa eccezione vorremmo guardare la linea 22di Book.javaper vedere che cosa potrebbe causare il NullPointerExceptionqui.

Esempio più scoraggiante con il codice della libreria

Di solito le tracce dello stack sono molto più complesse rispetto ai due esempi precedenti. Ecco un esempio (è lungo, ma mostra diversi livelli di eccezioni concatenate):

javax.servlet.ServletException: Something bad happened
    at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:60)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.example.myproject.ExceptionHandlerFilter.doFilter(ExceptionHandlerFilter.java:28)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.example.myproject.OutputBufferFilter.doFilter(OutputBufferFilter.java:33)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Caused by: com.example.myproject.MyProjectServletException
    at com.example.myproject.MyServlet.doPost(MyServlet.java:169)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:30)
    ... 27 more
Caused by: org.hibernate.exception.ConstraintViolationException: could not insert: [com.example.myproject.MyEntity]
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:64)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2329)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2822)
    at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)
    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:321)
    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
    at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
    at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:705)
    at org.hibernate.impl.SessionImpl.save(SessionImpl.java:693)
    at org.hibernate.impl.SessionImpl.save(SessionImpl.java:689)
    at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:344)
    at $Proxy19.save(Unknown Source)
    at com.example.myproject.MyEntityService.save(MyEntityService.java:59) <-- relevant call (see notes below)
    at com.example.myproject.MyServlet.doPost(MyServlet.java:164)
    ... 32 more
Caused by: java.sql.SQLException: Violation of unique constraint MY_ENTITY_UK_1: duplicate value(s) for column(s) MY_COLUMN in statement [...]
    at org.hsqldb.jdbc.Util.throwError(Unknown Source)
    at org.hsqldb.jdbc.jdbcPreparedStatement.executeUpdate(Unknown Source)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
    at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:57)
    ... 54 more

In questo esempio, c'è molto di più. Ciò di cui siamo maggiormente preoccupati è la ricerca di metodi che provengono dal nostro codice , che sarebbe qualsiasi cosa nel com.example.myprojectpacchetto. Dal secondo esempio (sopra), vorremmo prima cercare la causa principale, che è:

Caused by: java.sql.SQLException

Tuttavia, tutte le chiamate di metodo in base a ciò sono codici di libreria. Quindi passeremo al "Causato da" sopra di esso e cercheremo la prima chiamata del metodo proveniente dal nostro codice, che è:

at com.example.myproject.MyEntityService.save(MyEntityService.java:59)

Come negli esempi precedenti, dovremmo guardare in MyEntityService.javalinea 59, perché è lì che ha avuto origine questo errore (questo è un po 'ovvio cosa è andato storto, poiché SQLException indica l'errore, ma la procedura di debug è ciò che stiamo cercando).


3
@RobHruska - Molto ben spiegato. +1. Conoscete qualche parser che prende la traccia dell'eccezione come una stringa e fornisce metodi utili per analizzare stacktrace? - come getLastCausedBy () o getCausedByForMyAppCode ("com.example.myproject")
Andy Dufresne,

1
@AndyDufresne - Non ne ho mai incontrato nessuno, ma poi non ho nemmeno guardato davvero.
Rob Hruska,

1
Miglioramento suggerito: spiega la prima riga di una traccia dello stack che inizia con il Exception in thread "main"tuo primo esempio. Penso che sarebbe particolarmente utile spiegare che questa riga è spesso accompagnata da un messaggio, come il valore di una variabile, che può aiutare a diagnosticare il problema. Ho tentato di apportare una modifica da solo, ma sto lottando per adattare queste idee alla struttura esistente della tua risposta.
Apprendista di codice

5
Anche java 1.7 ha aggiunto "Soppresso:" - che elenca le tracce impilate delle eccezioni soppresse prima di visualizzare "Causato da:" per questa eccezione. Viene automaticamente utilizzato dal costrutto try-with-resource: docs.oracle.com/javase/specs/jls/se8/html/… e contiene eccezioni se ne è stato generato uno durante la chiusura delle risorse.
dhblah,

Esiste un JEP openjdk.java.net/jeps/8220715 che mira a migliorare ulteriormente la comprensibilità di NPE in particolare fornendo dettagli come "Impossibile scrivere il campo 'nullInstanceField' perché 'this.nullInstanceField' è null."
Mahatma_Fatal_Error il

80

Sto pubblicando questa risposta, quindi la risposta più in alto (se ordinata per attività) non è semplicemente sbagliata.

Che cos'è uno Stacktrace?

Uno stacktrace è uno strumento di debug molto utile. Mostra lo stack di chiamate (ovvero lo stack di funzioni richiamate fino a quel momento) nel momento in cui è stata generata un'eccezione non rilevata (o nel momento in cui lo stacktrace è stato generato manualmente). Questo è molto utile perché non mostra solo dove si è verificato l'errore, ma anche come il programma è finito in quel punto del codice. Questo porta alla domanda successiva:

Che cos'è un'eccezione?

Un'eccezione è ciò che l'ambiente di runtime utilizza per dirti che si è verificato un errore. Esempi popolari sono NullPointerException, IndexOutOfBoundsException o ArithmeticException. Ognuno di questi è causato quando si tenta di fare qualcosa che non è possibile. Ad esempio, verrà generata una NullPointerException quando si tenta di dereferenziare un oggetto Null:

Object a = null;
a.toString();                 //this line throws a NullPointerException

Object[] b = new Object[5];
System.out.println(b[10]);    //this line throws an IndexOutOfBoundsException,
                              //because b is only 5 elements long
int ia = 5;
int ib = 0;
ia = ia/ib;                   //this line throws an  ArithmeticException with the 
                              //message "/ by 0", because you are trying to
                              //divide by 0, which is not possible.

Come devo gestire Stacktraces / Exceptions?

Inizialmente, scopri cosa sta causando l'eccezione. Prova a cercare su Google il nome dell'eccezione per scoprire qual è la causa di tale eccezione. Il più delle volte sarà causato da un codice errato. Negli esempi sopra riportati, tutte le eccezioni sono causate da un codice errato. Quindi, per l'esempio di NullPointerException, puoi assicurarti che anon sia mai null in quel momento. Ad esempio, è possibile inizializzare ao includere un controllo come questo:

if (a!=null) {
    a.toString();
}

In questo modo, la linea offensiva non viene eseguita se a==null. Lo stesso vale per gli altri esempi.

A volte non puoi assicurarti di non ottenere un'eccezione. Ad esempio, se si utilizza una connessione di rete nel programma, non è possibile impedire al computer di perdere la sua connessione Internet (ad esempio, non è possibile impedire all'utente di disconnettere la connessione di rete del computer). In questo caso, probabilmente la libreria di rete genererà un'eccezione. Ora dovresti prendere l'eccezione e gestirla . Ciò significa che, nell'esempio con la connessione di rete, dovresti provare a riaprire la connessione o avvisare l'utente o qualcosa del genere. Inoltre, ogni volta che usi catch, prendi sempre solo l'eccezione che vuoi catturare, non usare dichiarazioni di catch generiche comecatch (Exception e)ciò catturerebbe tutte le eccezioni. Questo è molto importante, perché altrimenti potresti accidentalmente catturare l'eccezione sbagliata e reagire nel modo sbagliato.

try {
    Socket x = new Socket("1.1.1.1", 6789);
    x.getInputStream().read()
} catch (IOException e) {
    System.err.println("Connection could not be established, please try again later!")
}

Perché non dovrei usare catch (Exception e)?

Facciamo un piccolo esempio per mostrare perché non dovresti semplicemente cogliere tutte le eccezioni:

int mult(Integer a,Integer b) {
    try {
        int result = a/b
        return result;
    } catch (Exception e) {
        System.err.println("Error: Division by zero!");
        return 0;
    }
}

Ciò che questo codice sta cercando di fare è catturare il ArithmeticExceptioncausato da una possibile divisione per 0. Ma rileva anche un possibile NullPointerExceptionche viene lanciato se ao lo bsono null. Ciò significa che potresti ottenere un NullPointerExceptionma lo tratterai come un'eccezione aritmetica e probabilmente farai la cosa sbagliata. Nel migliore dei casi ti manca ancora che esistesse una NullPointerException. Roba del genere rende il debug molto più difficile, quindi non farlo.

TLDR

  1. Scopri qual è la causa dell'eccezione e correggila, in modo che non generi affatto l'eccezione.
  2. Se 1. non è possibile, prendere l'eccezione specifica e gestirla.

    • Non aggiungere mai un tentativo / cattura e quindi semplicemente ignorare l'eccezione! Non farlo!
    • Non usare mai catch (Exception e), prendere sempre specifiche eccezioni. Ciò ti farà risparmiare un sacco di mal di testa.

1
bella spiegazione del motivo per cui dovremmo evitare il mascheramento dei bug
Sudip Bhandari,

2
Sto pubblicando questa risposta, quindi la risposta più in alto (se ordinata per attività) non è una cosa semplicemente sbagliata, non ho idea di quale tu stia parlando dal momento che probabilmente ora è cambiato. Ma la risposta accettata è decisamente più interessante;)
AxelH,

1
Quello che intendevo era ormai stato cancellato, per quanto ne so. Sostanzialmente diceva "basta provare {} catch (Exception e) {} e ignorare tutti gli errori". La risposta accettata è molto più antica della mia risposta, quindi miravo a dare un po 'di una visione diversa sulla questione. Non penso che sia d'aiuto a chiunque semplicemente copiare la risposta di qualcun altro o coprire ciò che gli altri già hanno trattato bene.
Dakkaron,

È fuorviante dire "Non cogliere eccezioni", questo è solo un caso d'uso. Il tuo esempio è fantastico, ma che ne dici di dove ti trovi nella parte superiore del tuo thread thread (all'interno della sequenza)? Dovresti SEMPRE catturare l'eccezione (o forse Throwable) lì e registrarlo in modo che non svanisca invisibilmente (le eccezioni generate dall'esecuzione generalmente non vengono registrate correttamente a meno che tu non abbia impostato il tuo thread / logger per farlo).
Bill K

1
Non ho incluso questo caso speciale poiché conta solo con il multithreading. Nel thread singolo un'eccezione trapelata uccide il programma e viene registrata visibilmente. Se qualcuno non sa come gestire correttamente le eccezioni, di solito non sa ancora come utilizzare il multithreading.
Dakkaron

21

Per aggiungere a ciò che Rob ha menzionato. L'impostazione dei punti di interruzione nell'applicazione consente l'elaborazione passo-passo dello stack. Ciò consente allo sviluppatore di utilizzare il debugger per vedere in quale punto esatto il metodo sta facendo qualcosa di inaspettato.

Poiché Rob ha usato NullPointerException(NPE) per illustrare qualcosa di comune, possiamo aiutare a rimuovere questo problema nel modo seguente:

se abbiamo un metodo che accetta parametri come: void (String firstName)

Nel nostro codice vorremmo valutare che firstNamecontiene un valore, faremmo così:if(firstName == null || firstName.equals("")) return;

Quanto sopra ci impedisce di utilizzare firstNamecome parametro non sicuro. Pertanto, eseguendo controlli nulli prima dell'elaborazione, possiamo aiutare a garantire che il nostro codice verrà eseguito correttamente. Per espandere un esempio che utilizza un oggetto con metodi, possiamo guardare qui:

if(dog == null || dog.firstName == null) return;

Quanto sopra è l'ordine corretto per verificare la presenza di null, iniziamo con l'oggetto base, cane in questo caso, e quindi iniziamo a camminare lungo l'albero delle possibilità per assicurarci che tutto sia valido prima dell'elaborazione. Se l'ordine venisse invertito, un NPE potrebbe potenzialmente essere lanciato e il nostro programma andrebbe in crash.


Concordato. Questo approccio potrebbe essere usato per scoprire quale riferimento in un'istruzione è nullquando NullPointerExceptionsi sta esaminando a, per esempio.
Rob Hruska,

16
Quando si tratta di String, se si desidera utilizzare il metodo equals, penso che sia meglio usare la costante nella parte sinistra del confronto, in questo modo: Invece di: if (firstName == null || firstName.equals ("" )) ritorno; Uso sempre: if ((""). Equals (firstName)) Questo impedisce l'eccezione Nullpointer
Torres,

15

Esiste un'altra funzione stacktrace offerta dalla famiglia Throwable: la possibilità di manipolare le informazioni di traccia dello stack.

Comportamento standard:

package test.stack.trace;

public class SomeClass {

    public void methodA() {
        methodB();
    }

    public void methodB() {
        methodC();
    }

    public void methodC() {
        throw new RuntimeException();
    }

    public static void main(String[] args) {
        new SomeClass().methodA();
    }
}

Traccia dello stack:

Exception in thread "main" java.lang.RuntimeException
    at test.stack.trace.SomeClass.methodC(SomeClass.java:18)
    at test.stack.trace.SomeClass.methodB(SomeClass.java:13)
    at test.stack.trace.SomeClass.methodA(SomeClass.java:9)
    at test.stack.trace.SomeClass.main(SomeClass.java:27)

Traccia stack manipolata:

package test.stack.trace;

public class SomeClass {

    ...

    public void methodC() {
        RuntimeException e = new RuntimeException();
        e.setStackTrace(new StackTraceElement[]{
                new StackTraceElement("OtherClass", "methodX", "String.java", 99),
                new StackTraceElement("OtherClass", "methodY", "String.java", 55)
        });
        throw e;
    }

    public static void main(String[] args) {
        new SomeClass().methodA();
    }
}

Traccia dello stack:

Exception in thread "main" java.lang.RuntimeException
    at OtherClass.methodX(String.java:99)
    at OtherClass.methodY(String.java:55)

2
Non so come mi sento al riguardo ... con la natura del thread, consiglierei ai nuovi sviluppatori di non definire la propria traccia dello stack.
PeonProgrammer,

15

Per capire il nome : una traccia dello stack è un elenco di eccezioni (o puoi dire un elenco di "Cause per"), dall'eccezione più superficiale (ad esempio eccezione del livello di servizio) a quella più profonda (ad esempio eccezione del database). Proprio come il motivo per cui lo chiamiamo 'stack' è perché stack è First in Last out (FILO), l'eccezione più profonda si è verificata all'inizio, quindi una catena di eccezioni è stata generata una serie di conseguenze, l'eccezione di superficie è stata l'ultima uno è successo in tempo, ma lo vediamo in primo luogo.

Chiave 1 : Una cosa difficile e importante qui deve essere capita è: la causa più profonda potrebbe non essere la "causa principale", perché se si scrive un "codice errato", potrebbe causare un'eccezione al di sotto della quale è più profonda del suo livello. Ad esempio, una query sql errata può causare la reimpostazione della connessione SQLServerException nel bottem invece dell'errore syndax, che potrebbe essere proprio nel mezzo dello stack.

-> Individua la causa principale nel mezzo è il tuo lavoro. inserisci qui la descrizione dell'immagine

Chiave 2 : Un'altra cosa delicata ma importante è all'interno di ogni blocco "Cause by", la prima linea era lo strato più profondo e si trova al primo posto per questo blocco. Per esempio,

Exception in thread "main" java.lang.NullPointerException
        at com.example.myproject.Book.getTitle(Book.java:16)
           at com.example.myproject.Author.getBookTitles(Author.java:25)
               at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

Book.java:16 è stato chiamato da Auther.java:25 che è stato chiamato da Bootstrap.java:14, Book.java:16 è stata la causa principale. Qui allega un diagramma che ordina la pila di tracce in ordine cronologico. inserisci qui la descrizione dell'immagine


8

Solo per aggiungere agli altri esempi, ci sono classi interne (nidificate) che appaiono con il $segno. Per esempio:

public class Test {

    private static void privateMethod() {
        throw new RuntimeException();
    }

    public static void main(String[] args) throws Exception {
        Runnable runnable = new Runnable() {
            @Override public void run() {
                privateMethod();
            }
        };
        runnable.run();
    }
}

Si tradurrà in questa traccia dello stack:

Exception in thread "main" java.lang.RuntimeException
        at Test.privateMethod(Test.java:4)
        at Test.access$000(Test.java:1)
        at Test$1.run(Test.java:10)
        at Test.main(Test.java:13)

5

Gli altri post descrivono cos'è una traccia dello stack, ma può essere comunque difficile lavorarci.

Se si ottiene una traccia dello stack e si desidera tracciare la causa dell'eccezione, un buon punto di partenza per comprendere è utilizzare la console di traccia dello stack Java in Eclipse . Se usi un altro IDE potrebbe esserci una funzione simile, ma questa risposta riguarda Eclipse.

Innanzitutto, assicurati di avere tutte le tue fonti Java accessibili in un progetto Eclipse.

Quindi, nella prospettiva Java , fai clic sulla scheda Console (in genere nella parte inferiore). Se la vista Console non è visibile, vai all'opzione di menu Finestra -> Mostra vista e seleziona Console .

Quindi, nella finestra della console, fai clic sul seguente pulsante (a destra)

Pulsante console

e quindi selezionare Java Stack Trace Console dall'elenco a discesa.

Incolla la traccia dello stack nella console. Fornirà quindi un elenco di collegamenti al codice sorgente e qualsiasi altro codice sorgente disponibile.

Questo è ciò che potresti vedere (immagine dalla documentazione di Eclipse):

Diagramma dalla documentazione di Eclipse

La chiamata al metodo più recente effettuata sarà la parte superiore dello stack, ovvero la riga superiore (escluso il testo del messaggio). Scendendo la pila torna indietro nel tempo. La seconda linea è il metodo che chiama la prima linea, ecc.

Se si utilizza un software open source, potrebbe essere necessario scaricare e allegare al progetto le fonti se si desidera esaminare. Scarica i barattoli di origine, nel tuo progetto, apri la cartella Biblioteche referenziate per trovare il tuo vaso per il tuo modulo open-source (quello con i file di classe) quindi fai clic con il pulsante destro del mouse, seleziona Proprietà e collega il vaso di origine.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.