34 Debugging

Debugging ist ein essenzieller Bestandteil der Softwareentwicklung, um Fehler zu finden und die Funktionsweise einer Anwendung zu verstehen. In einer Spring Boot-Anwendung umfasst das Debugging nicht nur das Auffinden von logischen Fehlern, sondern auch das Verstehen der Interaktionen zwischen den verschiedenen Komponenten wie Beans, Konfigurationen, HTTP-Anfragen und dem Datenzugriff.

Dieses Kapitel gibt eine Übersicht über verschiedene Techniken und Werkzeuge, die Sie verwenden können, um Spring Boot-Anwendungen effektiv zu debuggen. Dabei wird sowohl auf die integrierten Debugging-Mechanismen als auch auf externe Tools und Best Practices eingegangen.

34.1 Debugging mit integrierten Tools

34.1.1 1. Aktivierung des Debug-Modus

Spring Boot bietet eine einfache Möglichkeit, den Debug-Modus zu aktivieren, der zusätzliche Informationen zur Laufzeit liefert, insbesondere beim Starten der Anwendung. Der Debug-Modus kann durch Hinzufügen der folgenden Zeile in der Datei application.properties aktiviert werden:

debug=true

Oder in der Datei application.yml:

debug: true

Wenn der Debug-Modus aktiviert ist, zeigt Spring Boot detaillierte Informationen über die Konfigurationen, die geladenen Beans und die Laufzeitumgebung an. Dies ist besonders hilfreich, um zu überprüfen, ob Beans korrekt erstellt und verdrahtet wurden.

34.1.2 2. Actuator zur Laufzeitüberwachung und Fehleranalyse

Spring Boot Actuator ist ein leistungsstarkes Tool, das zusätzliche Metriken, Überwachung und Management-Endpunkte bereitstellt. Es bietet verschiedene Informationen zur Laufzeit der Anwendung, die für das Debugging nützlich sind, z. B.:

34.1.2.1 Aktivierung von Actuator

Fügen Sie die Abhängigkeit zu Ihrem pom.xml hinzu:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Aktivieren Sie anschließend Actuator-Endpunkte in application.properties:

management.endpoints.web.exposure.include=*

Jetzt können Sie auf verschiedene Management-Endpunkte wie /actuator/health oder /actuator/beans zugreifen, um die Informationen zur Laufzeit zu überprüfen.

34.1.3 3. Verwendung von Logging

Logging ist eines der effektivsten Werkzeuge für das Debugging von Anwendungen. Spring Boot verwendet SLF4J in Kombination mit einer Logging-Implementierung wie Logback. Sie können den Logging-Level in der application.properties-Datei steuern:

logging.level.org.springframework=DEBUG
logging.level.com.example=TRACE

Die verschiedenen Logging-Level in Spring Boot sind:

Durch das Setzen des Logging-Levels auf DEBUG oder TRACE können Sie detaillierte Informationen über den Programmlauf erhalten.

34.1.3.1 Beispiel: Logging in einer Spring-Komponente

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class OrderService {

    private static final Logger logger = LoggerFactory.getLogger(OrderService.class);

    public void processOrder(String orderId) {
        logger.debug("Verarbeite Bestellung: {}", orderId);
        // Geschäftslogik hier
        logger.info("Bestellung {} erfolgreich verarbeitet", orderId);
    }
}

Hier wird ein Logger verwendet, um Informationen zur Verarbeitung einer Bestellung auszugeben. Sie können den Log-Level leicht anpassen, um detaillierte Informationen oder nur kritische Fehler anzuzeigen.

34.1.4 4. Breakpoints setzen und Debugging in der IDE

Die meisten modernen IDEs, wie IntelliJ IDEA, Eclipse oder Visual Studio Code, unterstützen das Debuggen von Spring Boot-Anwendungen direkt. Durch das Setzen von Breakpoints können Sie den Code schrittweise durchlaufen, Variablen inspizieren und den Programmfluss verstehen.

34.1.4.1 Schritte zum Debugging in IntelliJ IDEA:

  1. Setzen Sie einen Breakpoint in der gewünschten Zeile des Codes.
  2. Starten Sie die Anwendung im Debug-Modus (Shift + F9 oder durch Klicken auf den Debug-Button).
  3. Wenn die Ausführung den Breakpoint erreicht, stoppt die Anwendung. Sie können den aktuellen Zustand des Programms untersuchen.
  4. Verwenden Sie die Debugger-Tools, um durch den Code zu treten (Step Over, Step Into usw.).

Durch Breakpoints können Sie insbesondere in komplexen Interaktionen zwischen Beans und verschiedenen Schichten der Anwendung sehr effizient Fehler finden.

34.2 Debugging von Datenbankzugriffen

In vielen Fällen treten Fehler beim Zugriff auf die Datenbank auf. Spring Boot bietet verschiedene Tools, um Datenbankinteraktionen zu überwachen und Fehler zu erkennen.

34.2.1 1. SQL-Logging aktivieren

Spring Boot ermöglicht es, alle SQL-Statements, die von JPA oder JDBC ausgeführt werden, im Log anzuzeigen. Um SQL-Logging zu aktivieren, fügen Sie diese Zeile in application.properties hinzu:

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

Dadurch werden alle SQL-Befehle im Log ausgegeben, was bei der Analyse von Datenbankfehlern hilfreich ist.

34.2.2 2. Datenbank-Profiling mit spring.datasource-Properties

Sie können zusätzlich die Ausführungsdauer von SQL-Abfragen protokollieren, um Engpässe oder ineffiziente Abfragen zu identifizieren:

spring.datasource.hikari.configuration.maximum-pool-size=10
spring.datasource.hikari.configuration.connection-timeout=30000
spring.datasource.hikari.configuration.leak-detection-threshold=2000

Diese Konfigurationen helfen dabei, Verbindungsprobleme und langsame Abfragen zu identifizieren, indem sie Schwellenwerte für die SQL-Abfragezeit festlegen.

34.3 Debugging von HTTP-Anfragen

Das Debugging von HTTP-Anfragen und -Antworten ist besonders wichtig bei Webanwendungen.

34.3.1 1. Verwenden von spring-web Logging

Spring Boot erlaubt es, detaillierte Informationen über HTTP-Anfragen zu protokollieren, einschließlich der Anfragen, die an die Controller gesendet werden, und der Antworten. Aktivieren Sie das Logging für den org.springframework.web-Namespace:

logging.level.org.springframework.web=DEBUG

34.3.2 2. Verwendung von Tools wie Postman oder cURL

Um HTTP-Anfragen manuell zu testen und zu debuggen, können Sie Tools wie Postman oder cURL verwenden. Diese Werkzeuge ermöglichen es Ihnen, Anfragen mit verschiedenen Parametern, Headers und Payloads zu senden und die Antworten zu überprüfen.

Beispiel: cURL-Anfrage

curl -X POST http://localhost:8080/orders -H "Content-Type: application/json" -d '{"orderId": "12345"}'

Mit Postman können Sie HTTP-Anfragen visualisieren und die Antworten leicht analysieren, was besonders hilfreich für das Debuggen von REST-APIs ist.

34.3.3 3. Actuator Mappings

Der Actuator bietet den Endpunkt /actuator/mappings, der eine Übersicht über alle definierten Controller-Mappings und die entsprechenden Endpunkte liefert. Dies ist besonders nützlich, um zu überprüfen, ob die richtigen Mappings für Ihre URLs definiert sind.

curl http://localhost:8080/actuator/mappings

34.4 Debugging von Exceptions

34.4.1 1. Exception Handling und Fehlerseiten

Spring Boot verwendet standardmäßig die BasicErrorController, um Fehler zu behandeln. Sie können jedoch eigene Fehlerseiten für spezifische HTTP-Statuscodes definieren oder globale Exception-Handler erstellen.

Beispiel: Globaler Exception-Handler

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ModelAndView handleException(Exception ex) {
        ModelAndView mav = new ModelAndView("error");
        mav.addObject("message", ex.getMessage());
        return mav;
    }
}

In diesem Beispiel wird eine benutzerdefinierte Fehlerseite angezeigt, wenn eine Ausnahme auftritt.

34.4.2 2. Stack Traces analysieren

Stack Traces sind oft die erste Informationsquelle beim Debuggen von Fehlern. Wenn eine Exception geworfen wird, zeigt der Stack Trace die Fehlerursache und den genauen Codeabschnitt, in dem der Fehler aufgetreten ist. Achten Sie besonders auf:

34.5 Best Practices für Debugging

  1. Verwenden Sie Logging sinnvoll: Nutzen Sie verschiedene Logging-Level, um die richtige Menge an Informationen zu erhalten. Verwenden Sie DEBUG und TRACE-Level nur in Entwicklungsumgebungen, um überflüssige Logs in der Produktion zu vermeiden.

  2. Seien Sie präzise mit Breakpoints: Setzen Sie Breakpoints strategisch in Schlüsselbere

ichen des Codes, um den Programmablauf gezielt zu überprüfen.

  1. Isolieren Sie Fehler: Testen Sie kleine Teile der Anwendung isoliert, um Fehler schneller zu finden. Verwenden Sie Unit-Tests, um einzelne Methoden zu überprüfen, und setzen Sie Integrationstests für das Zusammenspiel mehrerer Komponenten ein.

  2. Verwenden Sie Actuator für Laufzeit-Insights: Actuator bietet viele nützliche Tools zur Laufzeitüberwachung und kann Ihnen helfen, Probleme in der Anwendung zu diagnostizieren, ohne den Code zu verändern.

34.6 tl;dr

Das Debugging in Spring Boot erfordert eine Kombination aus Logging, Breakpoints, Laufzeit-Überwachungs-Tools wie Actuator und externen Tools wie Postman oder cURL. Durch die Aktivierung des Debug-Modus und das richtige Setzen von Breakpoints in Ihrer IDE können Sie die Kontrolle über den Programmablauf gewinnen und Fehler effizient finden und beheben. Actuator-Endpunkte und SQL-Logging bieten zusätzliche Einblicke in die Anwendungslogik und die Interaktionen mit Datenbanken.