Debuggen von Spring-Anwendungen

1. Einleitung

Das Debuggen ist eines der wichtigsten Tools zum Schreiben von Software.

In diesem Tutorial werden einige Möglichkeiten beschrieben, wie wir Spring-Anwendungen debuggen können.

Wir werden auch sehen, wie Spring Boot, herkömmliche Anwendungsserver und IDEs dies vereinfachen.

2. Java Debug Args

Schauen wir uns zunächst an, was Java uns sofort bietet.

Standardmäßig aktiviert die JVM das Debuggen nicht . Dies liegt daran, dass das Debuggen zusätzlichen Overhead innerhalb der JVM verursacht. Dies kann auch ein Sicherheitsrisiko für öffentlich zugängliche Anwendungen sein.

Daher sollte das Debuggen nur während der Entwicklung und niemals auf Produktionssystemen durchgeführt werden.

Bevor wir einen Debugger anhängen können, müssen wir zuerst die JVM so konfigurieren, dass das Debuggen möglich ist. Dazu setzen wir ein Befehlszeilenargument für die JVM:

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000

Lassen Sie uns zusammenfassen, was jeder dieser Werte bedeutet:

-agentlib: jdwp

Aktivieren Sie den JDWP-Agenten (Java Debug Wire Protocol) in der JVM. Dies ist das Hauptbefehlszeilenargument, das das Debuggen ermöglicht.

transport = dt_socket

Verwenden Sie einen Netzwerk-Socket zum Debuggen von Verbindungen. Weitere Optionen sind Unix-Sockets und Shared Memory.

Server = y

Achten Sie auf eingehende Debugger-Verbindungen. Bei Einstellung auf n versucht der Prozess, eine Verbindung zu einem Debugger herzustellen, anstatt auf eingehende Verbindungen zu warten. Zusätzliche Argumente sind erforderlich, wenn dies auf n gesetzt ist .

suspend = n

Warten Sie beim Start nicht auf eine Debug-Verbindung. Die Anwendung wird normal gestartet und ausgeführt, bis ein Debugger angehängt wird. Bei der Einstellung y wird der Prozess erst gestartet, wenn ein Debugger angehängt ist.

Adresse = 8000

Der Netzwerkport, über den die JVM auf Debug-Verbindungen wartet.

Die obigen Werte sind Standardwerte und funktionieren für die meisten Anwendungsfälle und Betriebssysteme. Das JPDA-Verbindungshandbuch behandelt alle möglichen Werte detaillierter.

3. Spring Boot-Anwendungen

Spring Boot-Anwendungen können auf verschiedene Arten gestartet werden. Der einfachste Weg ist über die Befehlszeile mit dem Java- Befehl mit der Option -jar .

Um das Debuggen zu aktivieren, fügen wir einfach das Debug-Argument mit der Option -D hinzu :

java -jar myapp.jar -Dagentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000

Mit Maven können wir das angegebene Ausführungsziel verwenden , um unsere Anwendung mit aktiviertem Debugging zu starten:

mvn spring-boot:run -Dagentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000

Ebenso können wir mit Gradle die bootRun- Task verwenden. Zuerst müssen wir die Datei build.gradle aktualisieren, um sicherzustellen, dass Gradle Befehlszeilenargumente an die JVM übergibt:

bootRun { systemProperties = System.properties }

Jetzt können wir die bootRun- Task ausführen :

gradle bootRun -Dagentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000

4. Anwendungsserver

Während Spring Boot in den letzten Jahren sehr populär geworden ist, sind traditionelle Anwendungsserver in modernen Softwarearchitekturen immer noch weit verbreitet. In diesem Abschnitt erfahren Sie, wie Sie das Debuggen für einige der beliebtesten Anwendungsserver aktivieren.

Die meisten Anwendungsserver bieten ein Skript zum Starten und Stoppen von Anwendungen. Das Aktivieren des Debugs ist normalerweise nur eine Frage des Hinzufügens zusätzlicher Argumente zu diesem Skript und / oder des Festlegens zusätzlicher Umgebungsvariablen.

4.1. Kater

Das Startskript für Tomcat heißt Catalina.sh ( Catalina.bat unter Windows). Um einen Tomcat-Server mit aktiviertem Debug zu starten, können wir den Argumenten jpda voranstellen :

catalina.sh jpda start

Die Standard-Debug-Argumente verwenden einen Netzwerk-Socket, der Port 8000 mit suspend = n überwacht . Diese können durch Festlegen einer oder mehrerer der folgenden Umgebungsvariablen geändert werden: JPDA_TRANSPORT , JPDA_ADDRESS und JPDA_SUSPEND .

Wir können die Debug-Argumente auch vollständig kontrollieren, indem wir JPDA_OPTS setzen . Wenn diese Variable festgelegt ist, hat sie Vorrang vor den anderen JPDA-Variablen. Daher muss es sich um ein vollständiges Debug-Argument für die JVM handeln.

4.2. Wildfliege

Das Startskript für Wildfly lautet stand-alone.sh . Um einen Wildfly-Server mit aktiviertem Debug zu starten, können Sie –debug hinzufügen .

Der Standard-Debug-Modus verwendet einen Netzwerk-Listener an Port 8787 mit suspend = n . Wir können den Port überschreiben, indem wir ihn nach dem Argument –debug angeben .

Für mehr Kontrolle über das Debug-Argument können wir einfach die vollständigen Debug-Argumente zur Umgebungsvariablen JAVA_OPTS hinzufügen .

4.3. Weblogic

Das Startskript für Weblogic lautet startWeblogic.sh . Um einen Weblogic-Server mit aktiviertem Debug zu starten, können Sie die Umgebungsvariable debugFlag auf true setzen .

Der Standard-Debug-Modus verwendet einen Netzwerk-Listener an Port 8453 mit suspend = n . Wir können den Port überschreiben, indem wir die Umgebungsvariable DEBUG_PORT festlegen .

Für mehr Kontrolle über das Debug-Argument können wir einfach die vollständigen Debug-Argumente zur Umgebungsvariablen JAVA_OPTIONS hinzufügen .

Die neuesten Versionen von Weblogic bieten auch ein Maven-Plugin zum Starten und Stoppen von Servern. Dieses Plugin berücksichtigt dieselben Umgebungsvariablen wie das Startskript .

4.4. Glasfische

Das Startskript für Glassfish ist asadmin . Um einen Glassfish-Server mit aktiviertem Debug zu starten, müssen wir –debug verwenden :

asadmin start-domain --debug

Der Standard-Debug-Modus verwendet einen Netzwerk-Listener an Port 9009 mit suspend = n .

4.5. Steg

Der Jetty-Anwendungsserver enthält kein Startskript. Stattdessen werden Jetty-Server mit dem Befehl java gestartet .

Das Aktivieren des Debuggens ist daher so einfach wie das Hinzufügen der Standard-JVM-Befehlszeilenargumente.

5. Debuggen von einer IDE

Nachdem wir nun gesehen haben, wie das Debuggen in verschiedenen Anwendungstypen aktiviert wird, wollen wir uns die Verbindung eines Debuggers ansehen.

Jede moderne IDE bietet Debugging-Unterstützung. Dies umfasst sowohl die Möglichkeit, einen neuen Prozess mit aktiviertem Debugging zu starten, als auch die Möglichkeit, einen bereits ausgeführten Prozess zu debuggen.

5.1. IntelliJ

IntelliJ bietet erstklassige Unterstützung für Spring- und Spring Boot-Anwendungen. Debugging ist so einfach wie mit den zur Klasse der Navigation Hauptverfahren, Rechtsklick auf das Dreieck - Symbol, und wählen Sie Debug.

Wenn ein Projekt mehrere Spring Boot-Anwendungen enthält, stellt IntelliJ ein Toolfenster zum Ausführen des Dashboards bereit. In diesem Fenster können wir mehrere Spring Boot-Anwendungen von einem einzigen Ort aus debuggen:

Für Anwendungen, die Tomcat oder andere Webserver verwenden, können wir eine benutzerdefinierte Konfiguration für das Debuggen erstellen. Unter Ausführen > Konfigurationen bearbeiten gibt es eine Reihe von Vorlagen für die gängigsten Anwendungsserver:

Schließlich macht es IntelliJ sehr einfach, eine Verbindung zu einem laufenden Prozess herzustellen und ihn zu debuggen. Solange die Anwendung mit den richtigen Debug-Argumenten gestartet wurde , kann IntelliJ eine Verbindung herstellen, selbst wenn sie sich auf einem anderen Host befindet.

Auf dem Bildschirm Run / Debug Configurations (Konfigurationen ausführen / debuggen) können Sie in der Remote- Vorlage konfigurieren, wie eine Verbindung zur bereits ausgeführten Anwendung hergestellt werden soll:

Beachten Sie, dass IntelliJ nur den Hostnamen und den Debug-Port kennen muss. Der Einfachheit halber werden die richtigen JVM-Befehlszeilenargumente angegeben, die für die Anwendung verwendet werden sollen, die wir debuggen möchten.

5.2. Finsternis

Der schnellste Weg, um eine Spring Boot-Anwendung in Eclipse zu debuggen, besteht darin, im Paket-Explorer oder im Gliederungsfenster mit der rechten Maustaste auf die Hauptmethode zu klicken :

Die Standardinstallation von Eclipse unterstützt Spring oder Spring Boot nicht sofort. Auf dem Eclipse Marketplace ist jedoch ein Spring Tools-Add-On verfügbar, das Spring-Unterstützung bietet, die mit IntelliJ vergleichbar ist.

Insbesondere bietet das Add-On ein Boot-Dashboard, mit dem wir mehrere Spring Boot-Anwendungen von einem einzigen Ort aus verwalten können :

Das Add-On bietet auch eine Spring Boot Run / Debug-Konfiguration, mit der Sie das Debuggen einer einzelnen Spring Boot-Anwendung anpassen können. Diese benutzerdefinierte Ansicht ist an denselben Stellen verfügbar wie die Standardkonfiguration der Java-Anwendung .

Um einen bereits laufenden Prozess entweder lokal oder auf einem Remote-Host zu debuggen, können Sie die Remote-Java-Anwendungskonfiguration verwenden:

6. Debuggen mit Docker

Das Debuggen einer Spring-Anwendung in einem Docker-Container erfordert möglicherweise eine zusätzliche Konfiguration. Wenn der Container lokal ausgeführt wird und den Host-Netzwerkmodus nicht verwendet , kann auf den Debug-Port außerhalb des Containers nicht zugegriffen werden.

Es gibt verschiedene Möglichkeiten, den Debug-Port in Docker verfügbar zu machen.

Wir können –expose mit dem Docker- Befehl run verwenden :

docker run --expose 8000 mydockerimage

Wir können der Docker-Datei auch die EXPOSE- Direktive hinzufügen :

EXPOSE 8000

Wenn wir Docker Compose verwenden, können wir es der YAML hinzufügen:

expose: - "8000"

7. Fazit

In diesem Artikel haben wir gesehen, wie das Debuggen für jede Java-Anwendung aktiviert wird.

Durch einfaches Hinzufügen eines einzelnen Befehlszeilenarguments können wir problemlos jede Java-Anwendung debuggen.

Wir haben auch festgestellt, dass sowohl Maven als auch Gradle sowie die beliebtesten IDEs über spezielle Add-Ons verfügen, um das Debuggen von Spring- und Spring Boot-Anwendungen noch einfacher zu gestalten.