2012-06-13 11 views
7

Jakie możliwe działania można podjąć, aby dowiedzieć się, co poszło nie tak, jeśli ślad stosu błędu (który nie ma miejsca w głównym wątku) nie zawiera żadnej z twoich metod ? Pełne ślad w pytaniu:Wyjątek ze Stacktrace zawierający tylko wywołania biblioteki 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) 

ja obecnie próbuje uruchomić proces w tle przy użyciu SwingWorker że pod koniec aktualizuje JTable z nowymi danymi. Cały kod związany z tym zadaniem jest o wiele za duży, aby go opublikować i zastanawiam się, czy istnieje sposób na zawężenie źródła błędu.

+0

Śledzenie wyjątku RuntimeException jest naprawdę trudne, ponieważ nie są one wymagane do deklarowania ani do dokumentowania. – PeterMmm

Odpowiedz

5

StackTrace nie mogą zawierać żadnej z metod, ale to nie znaczy, że nie zawiera żadnej z utworzonych obiektów, w tym przypadku, problem najprawdopodobniej znajduje się w twoim TableModel.

W celu debugowania taki ślad stosu, ja zazwyczaj skorzystać z jednej z następujących metod:

  • zrobić trochę myślenia gdzie użyć tych standardowych klas JDK i patrząc na stacktrace można już uzyskać dość dobre wyobrażenie o tym, co idzie nie tak (jak widać na podstawie odpowiedzi na to pytanie, ponieważ mamy tylko ślad stosu)
  • umieść w swoim IDE "punkt przerwania wyjątku", który przynajmniej pozwoli ci użyć debuggera i uzyskać więcej informacji to, co jest dostępne w stosie stacktrace. Może ułatwić rozpoznawanie twoich obiektów i zorientowanie się, gdzie w kodzie znajduje się problem
  • dołączyć kod źródłowy JDK do projektu i umieścić zwykły punkt przerwania w kodzie źródłowym JDK, aby można było rozpocząć debugowanie.
  • Zamiast używać standardowego obiektu JDK, wykonaj np. anonimowe rozszerzenie zwykłej klasy JDK i nadpisanie problematycznej metody poprzez wywołanie super. To pozwala ci umieścić punkt przełomowy w problematycznej metodzie twojego problematycznego obiektu

To wszystko sprowadza się (z wyjątkiem pierwszego podejścia) do tego samego: uruchom mój debugger, aby dokładniej zbadać wszystkie powiązane obiekty co poszło nie tak. A gdy już zrozumiesz problem, naprawianie go jest zazwyczaj dość trywialne:

+0

Twoje metody są naprawdę interesujące, ale dodałbym jeszcze jeden: pomyśl o swoim kodzie. Na przykład krok po kroku na papierze. Debugowanie źródła JDK jest zabawne i pouczające, ale zazwyczaj nie ma tam sprawcy. – Carlo

+0

Bardzo dobra odpowiedź! –

+0

@ Carlo Nie chciałem debugować JDK. Zamiast tego poprzestań na debuggerze i sprawdź obiekty uczestniczące w stosie, które zwykle tworzyłeś we własnym kodzie. To może dać ci lepsze zrozumienie tego, w jakim kodzie utworzyłeś obiekt (np. Rozpoznając wartość przypisaną do pola, które możesz znać, to wartość utworzona w miejscu "x" w kodzie) – Robin

4

Twój JTable (lub twój nowy model) nie ma kolumn, powodując wyjątek ArrayIndexOutOfBoundsException, gdy wewnętrzny kod wywołuje DefaultTableColumnModel.getColumn.

Zapewnienie stolik ma rozmiar inny niż 0.

+0

Jest to prawda i dobrze i na pewno przydatna dla PO, ale nie jest odpowiedzią na to pytanie. –

+0

@ LucaGeretti Jak to nie jest odpowiedzią? Zapytał, jak go zawęzić, więc tak, moja odpowiedź nie odpowiada na to, ale OP najwyraźniej chce rozwiązać ten wyjątek. – Vulcan

+0

To dobra domniemana odpowiedź (spójrz dokładnie na ślad stosu w poszukiwaniu wskazówek), ale zastanawiam się, czy istnieje inny sposób. Ponadto umieszczam kilka druków w każdym punkcie, w którym model tabeli jest edytowany lub zmieniany. Nigdy nie ma mniej niż 70 kolumn i błąd zniknął (?????????). –

0

@Vulcan rozwiązał twój konkretny problem.

Ogólnie rzecz biorąc, jeśli ślad stosu nie obejmuje żadnej z twoich metod, poszukaj rzeczy, które wcześniej majstrowałeś i które są teraz wykonywane przez jakiś wątek demona. Na przykład w tym przypadku zepsułeś tabelę, a podczas losowania, bez użycia żadnej z twoich metod, wszystko poszło na południe.

Inne rzeczy, których należy szukać, to nieprawidłowe parametry konfiguracyjne, czy to pliki konfiguracyjne, parametry linii poleceń, zmienne środowiskowe i podobne.

I to jest to, że jeśli twoje metody nie spowodowały błędu, to jest to coś, co wydarzyło się zanim te pomieszane rzeczy się skończyły.

W bardzo rzadkich przypadkach, oczywiście, możesz znaleźć błąd!

0

Możesz debugować klasy java. *, Używając rt.jar i konfigurując IDE, aby umożliwić śledzenie i wkraczanie na te klasy. Następnie umieść punkt przerwania w górnych metodach śledzenia stosu i spróbuj określić, co zrobiłeś ze składnikiem wizualnym, który powoduje błąd.

Alternatywnie analizując tylko ślad stosu, można podać napiwek dotyczący problemu, na przykład w tym przypadku jest to linia o problematycznych parametrach, tak jak w kolumnach tabeli. Indeks 0 >= 0 podaje kolejną wskazówkę dotyczącą liczby kolumn oczekiwanych lub naprawdę obecnych.

Ogólnie rzecz biorąc, niezbędne jest dogłębne zrozumienie zachowania komponentów w celu ustalenia przyczyny.

1

Zazwyczaj te niby ślady stosu (NPE lub IndexOutOfBounds podczas układu Swing/malowania, zobacz RepaintManager/Spójrz & Poczuj zajęcia w ślad) są powodowane przez nie tworzenie/modyfikowanie komponentów Swing na EDT (wysyłka wątek event) . Obejmuje to aktualizację modelu danych Swing, takiego jak TableModel, który powoduje zdarzenia pożaru, które spowodują odświeżenie.

Szukaj w "Samouczek współdziałania z java swing", aby uzyskać więcej informacji.