2012-06-13 10 views
7

Quale possibile linea di condotta si può intraprendere per scoprire cosa è andato storto se la traccia dello stack di un errore (che non si verifica nel thread principale) non contiene nessuno dei metodi ? La traccia completa in questione:Eccezione con Stacktrace che contiene solo chiamate in libreria Java

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0 
    at java.util.Vector.elementAt(Unknown Source) 
    at javax.swing.table.DefaultTableColumnModel.getColumn(Unknown Source) 
    at javax.swing.plaf.basic.BasicTableHeaderUI.getHeaderRenderer(Unknown Source) 
    at javax.swing.plaf.basic.BasicTableHeaderUI.getHeaderHeight(Unknown Source) 
    at javax.swing.plaf.basic.BasicTableHeaderUI.createHeaderSize(Unknown Source) 
    at javax.swing.plaf.basic.BasicTableHeaderUI.getPreferredSize(Unknown Source) 
    at javax.swing.JComponent.getPreferredSize(Unknown Source) 
    at javax.swing.ViewportLayout.preferredLayoutSize(Unknown Source) 
    at java.awt.Container.preferredSize(Unknown Source) 
    at java.awt.Container.getPreferredSize(Unknown Source) 
    at javax.swing.JComponent.getPreferredSize(Unknown Source) 
    at javax.swing.ScrollPaneLayout.layoutContainer(Unknown Source) 
    at java.awt.Container.layout(Unknown Source) 
    at java.awt.Container.doLayout(Unknown Source) 
    at java.awt.Container.validateTree(Unknown Source) 
    at java.awt.Container.validate(Unknown Source) 
    at javax.swing.RepaintManager.validateInvalidComponents(Unknown Source) 
    at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source) 
    at java.awt.event.InvocationEvent.dispatch(Unknown Source) 
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
    at java.awt.EventQueue.access$000(Unknown Source) 
    at java.awt.EventQueue$1.run(Unknown Source) 
    at java.awt.EventQueue$1.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) 
    at java.awt.EventQueue.dispatchEvent(Unknown Source) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.run(Unknown Source) 

stavo attualmente cercando di eseguire un processo in background utilizzando SwingWorker che alla fine aggiorna un JTable con nuovi dati. Tutto il codice relativo a questa attività è troppo grande per postare qui e mi chiedo se c'è un modo per restringere la fonte dell'errore.

+0

Il rilevamento di un RuntimeException è molto difficile, poiché non è obbligatorio dichiararlo o documentarlo. – PeterMmm

risposta

5

La stacktrace non può contenere uno qualsiasi dei vostri metodi, ma non significa che non contiene uno qualsiasi degli oggetti creati, in questo caso, il problema molto probabilmente si trova nel tuo TableModel.

Al fine di eseguire il debug di un tale traccia dello stack, io di solito utilizzare uno dei seguenti metodi:

  • fare un po 'di pensiero in cui si utilizza le classi JDK standard e guardando lo stacktrace si può già ottenere un discreto idea di cosa vada storto (come si può vedere dalle risposte a questa domanda poiché abbiamo solo la traccia dello stack)
  • inserisci un 'Punto di interruzione eccezione' nel tuo IDE che ti permetterà almeno di usare il tuo debugger e ottenere maggiori informazioni allora ciò che è disponibile in uno stacktrace. Potrebbe rendere più facile riconoscere i tuoi oggetti e avere un'idea di dove si trova il problema
  • allegare il codice sorgente JDK al progetto e inserire un punto di interruzione regolare nel codice sorgente JDK, in modo da poter avviare il debug.
  • Invece di utilizzare l'oggetto JDK standard, effettuare ad es. un'estensione anonima della normale classe JDK e scavalca il metodo problematico chiamando semplicemente super. Ciò consente di inserire un punto di interruzione nel metodo problematico dell'oggetto problematico

Tutto questo si riduce (eccetto il primo approccio) allo stesso: avvia il mio debugger in modo da poter esaminare tutti gli oggetti correlati più attentamente per capire cosa va storto E una volta compreso il problema, risolverlo è quasi sempre banale

+0

I tuoi metodi sono tutti molto interessanti, ma ne aggiungerei uno in più: pensa al tuo codice. Ad esempio passandoci sopra sulla carta. Il debug della sorgente JDK è in qualche modo divertente e istruttivo, ma di solito il colpevole non è presente. – Carlo

+0

Ottima risposta! –

+0

@ Carlo. Non intendevo eseguire il debug del JDK. Piuttosto, basta che il debugger si fermi qui e ispezioni gli oggetti coinvolti nello stacktrace, che in genere è stato creato nel proprio codice. Questo potrebbe darti una migliore comprensione del tuo codice creato dall'utente (ad esempio riconoscendo un valore assegnato a un campo potresti sapere che è il valore che hai creato nella posizione 'x' nel tuo codice) – Robin

4

Il tuo JTable (o il tuo nuovo modello) non ha colonne, causando un ArrayIndexOutOfBoundsException quando il codice interno chiama DefaultTableColumnModel.getColumn.

Assicuratevi che il vostro tavolo ha una dimensione diversa da 0.

+0

Questo è vero e preciso e sicuramente utile per l'OP, ma non è una risposta alla domanda. –

+0

@LucaGeretti Come non è una risposta? Ha chiesto come restringerlo, quindi sì, la mia risposta non è esattamente la risposta, ma OP ovviamente vuole risolvere l'eccezione. – Vulcan

+0

È una buona risposta implicita (guarda attentamente la traccia dello stack per gli indizi) ma mi chiedo se c'è un altro modo. Inoltre, inserisco alcuni println in ogni punto in cui il modello di tabella viene modificato o modificato. Non ha mai meno di 70 colonne e l'errore è scomparso (????????). –

0

@Vulcan ha risolto il tuo problema specifico.

In generale, se la traccia dello stack non coinvolge nessuno dei tuoi metodi, cerca le cose con cui hai armeggiato prima e che ora viene eseguita da qualche thread daemon. Per esempio in questo caso hai incasinato la tabella, e al momento del disegno, senza usare nessuno dei tuoi metodi, le cose sono andate a sud.

Altre cose da cercare sono parametri di configurazione non validi, che si tratti di file di configurazione, parametri della riga di comando, variabili di ambiente e simili.

E questo è quello, se i tuoi metodi non hanno causato l'errore, allora è qualcosa che è accaduto prima che le cose incasinate.

In casi molto rari, ovviamente, è possibile che si trovi un bug!

0

È possibile eseguire il debug delle classi java. * Utilizzando rt.jar e configurando l'IDE per consentire la traccia e l'avanzamento in queste classi. Quindi inserisci un punto di interruzione nei metodi superiori della traccia dello stack e prova a capire cosa hai fatto con il componente visivo che causa l'errore.

In alternativa, solo analizzando la traccia dello stack potresti dare un consiglio sul problema, ad esempio in questo caso è getColumn() la riga problematica, quindi dovrebbe essere qualsiasi cosa tu abbia fatto con le colonne della tabella. L'indice 0 >= 0 fornisce un altro suggerimento sul numero di colonne previste o realmente presenti.

In genere è necessaria una profonda comprensione del comportamento dei componenti al fine di comprendere la causa principale.

1

In genere questo tipo di tracce di stack (NPE o IndexOutOfBounds durante il layout/verniciatura di Swing, vedere le classi RepaintManager/Look & Feel nella traccia) sono causati dalla mancata creazione/modifica dei componenti di Swing sull'EDT (thread di invio evento) . Ciò include l'aggiornamento del modello di dati di Swing come TableModel che genera eventi che provocheranno un repaint.

Cerca "tutorial sulla concorrenza di swing java" per ulteriori informazioni.