Debugging a Java application running inside a Docker container can be a straightforward process if you follow these simple steps. In this guide, I will walk you through the necessary steps to attach a debugger to your Java application.

Java Application

First of all, let's create a sample Java application to debug. We'll be using Javalin for creating a simple API.

Project Structure

Here is the folder structure for our project:

Maven Configuration (pom.xml)

Create the pom.xml file with the following content:

Docker Configuration (Dockerfile)

Create the Dockerfile with the following content:

Application Code (Main.java)

Create the main application file Main.java under src/main/java/dev/yasint/:

Building the Application

To build the application, run the following commands:

Running the Application in Docker

Now let's build and run the Docker container with our application. We can use the following commands:

Now our application should be running and accessible at http://localhost:7070/hello.

Attaching the Debugger

Now the fun part begins! To enable debugging, we need to modify the Docker configuration to include the necessary JVM options.

Debugging Configuration

Before configuring our IDEs, we need to adjust how we run our Java application. Specifically, we need to enable the Java Debug Wire Protocol (JDWP). JDWP is the protocol that facilitates communication between a debugger and the Java Virtual Machine (JVM) being debugged (referred to as the target VM). Note that JDWP is optional and may not be available in all JDK implementations. Its presence allows for the use of the same debugger across different JVMs.

I am using JDK 21 and the following option to enable debugging. You can use the same option if you are using JDK 9 or later.

However, if you're using a JDK version below 9, the configuration is slightly different. Below, I outline how to configure various versions of the JDK.

The next step is to modify the Dockerfile's CMD command to include the debugging configuration:

Running the Application with Debugging Enabled

Rebuild and run the Docker container with the updated configuration:

Configuring Your IDE

Now we can set up our IDE to connect to the remote JVM for debugging.

For IntelliJ IDEA:

  1. Go to Run > Edit Configurations.
  2. Click the + icon and select Remote JVM Debug.
  3. Configure the remote debugger with the following settings:
    • Name: MyApp (literally anything you want)
    • Host: localhost
    • Port: 5005
  4. Apply the changes and click OK.

For Eclipse:

I don't have a detailed explanation for configuring Eclipse, but the steps are quite similar to what I've described above. For a reasonably up-to-date guide, I found this helpful article from Eclipse.org: Eclipse Debug Configuration.

Starting the Debugging Session šŸž

Start the remote debugging session from your IDE. You should now be connected to the JVM running inside your Docker container. You can set breakpoints, inspect variables, and step through your code as if it were running locally.

Starting the debugging session in IntelliJ

Conclusion

By following these steps, we have successfully created a simple Java application with Javalin, packaged it into a Docker container, and attached a debugger to it. This setup allows for effective debugging, enabling you to troubleshoot and optimize your application efficiently.

Well, now what?

You can navigate to more writings from here. Connect with me on LinkedIn for a chat.