1. 序章

デバッグは、ソフトウェアを作成するための最も重要なツールの1つです。

このチュートリアルでは、Springアプリケーションをデバッグする方法のいくつかを確認します。

We’ll also demonstrate how Spring Boot, traditional application servers, and IDEs simplify this.

2. Javaデバッグ引数

まず、Javaが箱から出して何を提供するかを見てみましょう。

By default, the JVM doesn’t enable debugging. これは、デバッグによってJVM内に追加のオーバーヘッドが発生するためです。 また、公的にアクセス可能なアプリケーションのセキュリティ上の懸念事項になる可能性もあります。

Therefore, debugging should only be performed during development, and never on production systems.

デバッガーを接続する前に、まずデバッグを許可するようにJVMを構成する必要があります。 We’ll do this by setting a command line argument for the JVM:

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

これらの各値の意味を分析してみましょう。

-agentlib:jdwp

This enables the Java Debug Wire Protocol (JDWP) agent inside the JVM. これはデバッグを可能にするメインコマンドライン引数です。

Transportation = dt_socket

This uses a network socket for debug connections. その他のオプションには、Unixソケットと共有メモリが含まれます。

server = y

This listens for incoming debugger connections. n に設定すると、プロセスは着信接続を待つのではなく、デバッガーへの接続を試みます。 これがnに設定されている場合は、追加の引数が必要です。

suspend = n

This means don’t wait for a debug connection at startup. アプリケーションは、デバッガーが接続されるまで正常に起動して実行されます。 When set to y, the process won’t start until a debugger is attached.

アドレス=8000

This is the network port that the JVM will listen on for debug connections.

上記の値は標準であり、ほとんどのユースケースとオペレーティングシステムで機能します。 The JPDA connection guide covers all the possible values in more detail.

2.1. JDK9+のバインディングアドレス

On JDK8 and below, setting the address property to port number only (address=8000 in the example above) means that the JVM listens on all available IP addresses. したがって、リモート接続は箱から出して利用できます。

これは、セキュリティ上の理由からJDK9+で変更されました。 現在、デフォルトの設定ではローカルホスト接続のみが許可されています。

This means that if we want to make remote connections available, we need to either prefix the port number with the hostname, address=myhost:8000, or use an asterisk to listen on all available IP addresses, address=*:8000.

3. SpringBootアプリケーション

There are several ways to start Spring Boot applications. The simplest way is from the command line using the java command with the -jar option.

To enable debugging, we simply add the debug argument using the -D option:

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

Mavenを使用すると、提供されている run の目標を使用して、デバッグを有効にしてアプリケーションを開始できます。

mvn spring-boot:run -Dspring-boot.run.jvmArguments="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000"

Similarly, with Gradle, we can use the bootRun task. まず、 build.gradle ファイルを更新して、Gradleがコマンドライン引数をJVMに渡すようにする必要があります。

bootRun {
   systemProperties = System.properties
}

これで、bootRunタスクを実行できます。

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

4. アプリケーションサーバー

Spring Bootは近年非常に人気がありますが、従来のアプリケーションサーバーは、現在でも最新のソフトウェアアーキテクチャで非常に普及しています。 このセクションでは、いくつかのより一般的なアプリケーションサーバーのデバッグを有効にする方法を見ていきます。

ほとんどのアプリケーションサーバーは、アプリケーションを開始および停止するためのスクリプトを提供します。 デバッグを有効にするには、通常、このスクリプトに引数を追加したり、環境変数を追加したりするだけです。

4.1. Tomcat

Tomcat の起動スクリプトは、 catalina.sh (Windowsでは catalina.bat )という名前です。 To start a Tomcat server with debug enabled, we can prepend jpda to the arguments:

catalina.sh jpda start

デフォルトのデバッグ引数は、 suspend =nでポート8000をリッスンするネットワークソケットを使用します。 これらは、 JPDA_TRANSPORT JPDA_ADDRESS 、およびJPDA_SUSPENDの1つ以上の環境変数を設定することで変更できます。

JPDA_OPTS を設定することで、デバッグ引数を完全に制御することもできます。 この変数を設定すると、他のJPDA変数よりも優先されます。 Thus, it must be a complete debug argument for the JVM.

4.2. Wildfly

Wildflyの起動スクリプトはstand-alone.shです。 To start a Wildfly server with debug enabled, we can add –debug.

デフォルトのデバッグモードでは、 suspend =nのポート8787でネットワークリスナーが使用されます。 –debug 引数の後にポートを指定することで、ポートをオーバーライドできます。

デバッグ引数をさらに制御するには、完全なデバッグ引数をJAVA_OPTS環境変数に追加するだけです。

4.3. Weblogic

Weblogicの起動スクリプトはstartWeblogic.shです。 To start a Weblogic server with debug enabled, we can set the environment variable debugFlag to true.

デフォルトのデバッグモードでは、 suspend =nのポート8453でネットワークリスナーが使用されます。 DEBUG_PORT 環境変数を設定することで、ポートをオーバーライドできます。

デバッグ引数をさらに制御するには、完全なデバッグ引数をJAVA_OPTIONS環境変数に追加するだけです。

最新バージョンのWeblogicには、サーバーを起動および停止するためのMavenプラグインも用意されています。 このプラグインは、起動スクリプトと同じ環境変数を受け入れます。

4.4. Glassfish

Glassfishの起動スクリプトはasadminです。 To start a Glassfish server with debug enabled, we have to use –debug:

asadmin start-domain --debug

デフォルトのデバッグモードでは、 suspend =nのポート9009でネットワークリスナーを使用します。

4.5. 桟橋

The Jetty application server doesn’t come with a startup script. 代わりに、Jettyサーバーはjavaコマンドを使用して起動されます。

したがって、デバッグの有効化は、標準のJVMコマンドライン引数を追加するのと同じくらい簡単です。

5. IDEからのデバッグ

Now that we’ve seen how to enable debugging in various application types, let’s look at connecting a debugger.

最新のIDEはすべて、デバッグサポートを提供します。 これには、デバッグを有効にして新しいプロセスを開始する機能と、すでに実行中のプロセスをデバッグする機能の両方が含まれます。

5.1. IntelliJ

IntelliJ は、SpringおよびSpringBootアプリケーションのファーストクラスのサポートを提供します。 Debugging is as simple as navigating to the class with the main method, right-clicking the triangle icon, and choosing Debug:

プロジェクトに複数のSpringBootアプリケーションが含まれている場合、IntelliJはダッシュボードの実行ツールウィンドウを提供します。 このウィンドウでは、複数のSpringBootアプリケーションを1か所からデバッグできます。

Tomcatまたは他のWebサーバーを使用するアプリケーションの場合、デバッグ用のカスタム構成を作成できます。 Under Run > Edit Configurations, there are a number of templates for the most popular application servers:

最後に、IntelliJを使用すると、実行中のプロセスに非常に簡単に接続してデバッグできます。 アプリケーションが適切なデバッグ引数で開始されている限り、IntelliJは、別のホスト上にある場合でも、アプリケーションに接続できます。

On the Run/Debug Configurations screen, the Remote template will let us configure how we want to attach to the already running application:

IntelliJが知っている必要があるのはホスト名とデバッグポートだけであることに注意してください。 As a convenience, it tells us the proper JVM command line arguments that should be used on the application that we want to debug.

5.2. Eclipse

EclipseでSpringBootアプリケーションをデバッグする最も簡単な方法は、 PackageExplorerまたはOutlineウィンドウからmainメソッドを右クリックすることです。

The default installation of Eclipse doesn’t support Spring or Spring Boot out of the box. ただし、EclipseMarketplaceにはSpring Toolsアドオンがあり、IntelliJに匹敵するSpringサポートを提供します。

Most notably, the add-on provides a Boot Dashboard that lets us manage multiple Spring Boot applications from a single place:

The add-on also provides a Spring Boot Run/Debug Configuration that allows us to customize the debug of a single Spring Boot application. このカスタマイズされたビューは、標準のJavaアプリケーション構成と同じ場所から利用できます。

ローカルまたはリモートホストですでに実行されているプロセスをデバッグするには、リモートJavaアプリケーション構成を使用できます。

6. Dockerを使用したデバッグ

Dockerコンテナ内のSpringアプリケーションをデバッグするには、追加の構成が必要になる場合があります。 If the container is running locally, and isn’t using host network mode, then the debug port won’t be accessible outside the container.

Dockerでデバッグポートを公開する方法はいくつかあります。

–exposedockerrunコマンドで使用できます。

docker run --expose 8000 mydockerimage

EXPOSEディレクティブをDockerfileに追加することもできます。

EXPOSE 8000

Or, if we’re using Docker Compose, we can add it into the YAML:

expose:
 - "8000"

7. 結論

In this article, we discussed how to enable debugging for any Java application.

単一のコマンドライン引数を追加するだけで、任意のJavaアプリケーションを簡単にデバッグできます。

We also learned that both Maven and Gradle, as well as most popular IDEs, all have specialized add-ons to make debugging Spring and Spring Boot applications even easier.