EMZETT.
Login

Troubleshooting in Java

Kurz: Troubleshooting heißt systematische Fehlersuche. In Java liest man dazu zuerst die Fehlermeldung samt Stacktrace, grenzt die Stelle ein und prüft Annahmen mit Ausgaben, Debugger oder Tests.

Genauer: Die meisten Fehler verraten sich selbst: Der Stacktrace nennt die Ausnahme, die Meldung und die Aufrufkette mit Datei und Zeile. Wer den lesen kann, löst einen Großteil der Probleme in Minuten.

Im Detail

1. Fehlermeldung lesen (von oben nach unten):

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "name" is null
    at Person.laenge(Person.java:12)
    at Main.main(Main.java:5)

Oben: Art und Grund der Ausnahme. Darunter: die erste Zeile ist die Stelle, wo es knallte. Die weiteren zeigen, wer sie aufrief. Erste eigene Zeile suchen, nicht die in Bibliotheken.

2. Typische Fälle:

MeldungUrsacheAbhilfe
NullPointerExceptionReferenz ist nullWo wird die Variable gesetzt? Auf null prüfen, Optional nutzen
ArrayIndexOutOfBoundsExceptionIndex außerhalb 0 … length-1Schleifengrenzen prüfen
ClassCastExceptionFalscher Castinstanceof prüfen, Generics nutzen
NumberFormatExceptionText ist keine ZahlEingabe prüfen / abfangen
ClassNotFoundException, NoClassDefFoundErrorKlasse nicht auf dem KlassenpfadAbhängigkeit/Pfad prüfen
StackOverflowErrorRekursion ohne EndeAbbruchbedingung prüfen
OutOfMemoryErrorHeap voll oder Speicherleck-Xmx erhöhen, Heap-Dump analysieren
cannot find symbol (Compiler)Tippfehler, Import fehltSchreibweise, Import prüfen
UnsupportedClassVersionErrorBytecode neuer als JREJava-Version angleichen

3. Vorgehen:

  • Reproduzieren: Erst wenn der Fehler auf Knopfdruck auftritt, lässt er sich sicher beheben.
  • Eingrenzen: Variablen ausgeben oder mit dem Debugger Haltepunkte setzen und Zeile für Zeile durchgehen. Halbierungsmethode: Liegt der Fehler vor oder nach dieser Stelle?
  • Nur eine Änderung auf einmal und danach testen.
  • Neuere Änderungen verdächtigen: git diff und git bisect finden den Auslöser.
  • Werkzeuge: IDE-Debugger, jstack (Thread-Dump bei Hängern), jmap/Heap-Dump und VisualVM (Speicher), Logging.
  • Absichern: Aus jedem gefundenen Fehler einen Unit-Test machen, damit er nicht wiederkommt.
  • Rubber-Duck-Debugging: Das Problem laut erklären (einer Gummiente) deckt oft den Denkfehler auf.

Siehe auch: Exceptions, Debugging, Error Codes