0%
July 2, 2023

Remote Debugger for Spring Application

java

springboot

Reference

Docker Image

At the project root level of our spring application, we make a simple Dockerfile as follows

FROM maven:3.8.3-openjdk-17
RUN mkdir -p /usr/src/wbbackendboot
COPY . /usr/src/wbbackendboot
WORKDIR /usr/src/wbbackendboot

RUN mvn install
EXPOSE 8090

We intentionally not to start the program via CMD or ENTRYPOINT because

  • We want the docker image to run in 3 environments using 3 diffeent property files.
  • We want to debug the docker image whenever we want.

Having CMD and ENTRYPOINT to be empty leaves the room for such flexibility.

docker-compose file

1version: "3.3"
2services:
3  wb-backend-boot:
4    image: wb-backend:1.0
5    command:
6      - /bin/bash
7      - -c
8      - |
9        sed -i s/spring.redis.host=127.0.0.1/spring.redis.host=redis/ /usr/src/wbbackendboot/src/main/resources/application-local.properties
10        mvn install
11        java -jar -Dspring.profiles.active=local target/wb_backend-0.0.1-SNAPSHOT.jar
12    environment:
13      - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
14    ports:
15        - 8090:8090
16        - 5005:5005
17      restart: always
18    volumes:
19      - type: bind
20        source: ~/.aws
21        target: /root/.aws # it needs absolute path, when I run cd ~/.aws && pwd, I get /root/.aws
22        read_only: true
23  redis:
24    image: redis
25    ports:
26      - 6379:6379
Deploying in Different Environment

In line 11 we have

  • -Dspring.profiles.active=local

This is a built-in param for spring project, which make spring pick application-local.properties as the property file (same role as environment variable in nodejs).

Remote Debugger

In line 13 we have

  • JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
  • The backend can still be accessed through 8090, and in addition we can remote debug the spring project via port 5005.

  • Once the docker container is running, we can debug the spring project inside the container via port 5005 with the following config in vscode:

    {
      "version": "0.2.0",
      "configurations": [
        {
          "type": "java",
          "name": "Debug (Attach)",
          "projectName": "MyApplication",
          "request": "attach",
          "hostName": "localhost",
          "port": 5005
        }
      ]
    }

    Or otherwise we can as well remote debug in IntelliJ:

  • Although it is conveninent, unlike local debugger we cannot access the variable and play around with methods of the object as in the debug console of vscode.

    But we can still see the detailed of each variable captured in the debugger on the left column of vscode. We can read it, but cannot access it.

Redis

Since we run 2 containers in the same network, our container named wb-backend-boot will connect to the redis service by using redis (container name) as the host. This explains line 9 for text substitution of property file.