user3067870
user3067870

Reputation: 596

How to use Spring Dev Tools Live Reload with Maven Multi-Project running in Docker Compose

I have a Spring Boot, Maven multi-module project which I am running using docker compose. The project runs with no problems, however, I cannot get live-reloading working using Spring Dev Tools.

My project structure is:

my-service
- api (submodule)
- domain (submodule)
- entity (submodule)
- graphql (main-module)
- repository (submodule)

My project's Dockerfile:

FROM openjdk:21-jdk-slim as dependencies

WORKDIR /app
COPY . .

RUN ./mvnw dependency:go-offline

FROM dependencies as build

RUN ./mvnw package spring-boot:repackage

FROM openjdk:21-jdk-slim as runtime

COPY --from=build /app/graphql/target/graphql-0.0.1-SNAPSHOT.jar /app/graphql/target/
EXPOSE 8080
CMD ["java", "-jar", "/app/graphql/target/graphql-0.0.1-SNAPSHOT.jar"]

FROM openjdk:21-jdk-slim as debug

COPY --from=build /app/graphql/target/graphql-0.0.1-SNAPSHOT.jar /app/graphql/target/
EXPOSE 5006
CMD ["java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5006", "-jar", "/app/graphql/target/graphql-0.0.1-SNAPSHOT.jar"]

My docker-compose.yml:

version: "3.8"

services:
  my-service:
    build:
      context: .
      target: debug
    environment:
      - SPRING_PROFILES_ACTIVE=local
    volumes:
      - "~/.m2:/root/.m2"
      - ".:/app"
    ports:
      - "8080:8080"
      - "5050:5006"

I have been scouring the internet for any documentation on achieving live-reloading with a dockerized multi-module spring boot project, unfortunately I was unable to find guidance.

Does anyone have knowledge on how to do this properly?

I have been attempting to follow this article: https://medium.com/@kishieel/dockerize-your-spring-boot-application-with-hot-reloading-44ada09adf20, but when I started the service and issued a GraphQL query, it just kept getting errors about the class loader:

my-service-1  | java.lang.ClassCastException: class com.example.myservice.repository.MyClass cannot be cast to class com.example.myservice.repository.MyClass (com.example.myservice.repository.MyClass is in unnamed module of loader 'app'; com.example.myservice.repository.MyClass is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @3bbdbc95)

Upvotes: 0

Views: 249

Answers (1)

user3067870
user3067870

Reputation: 596

I finally figured out that this was actually an issue with the DynamoDBEnhanced Client, I had to switch from using annotation based table schema definitions to static table schema definition. You can read about it here, or here. Once I switched, it live-reloading started working without the aforementioned exception.

This was my final docker setup for spring dev tools live-reloading:

docker-entry point.sh

#!/bin/bash

dos2unix mvnw

./mvnw spring-boot:run -Dspring-boot.run.jvmArguments="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005" &

while true; do
  inotifywait -e modify,create,delete,move -r /app && ./mvnw compile
done

Dockerfile:

FROM openjdk:21-jdk-slim as dependencies

WORKDIR /app
COPY . .

FROM dependencies as build

RUN ./mvnw package spring-boot:repackage

FROM openjdk:21-jdk-slim as runtime

COPY --from=build /app/graphql/target/graphql-0.0.1-SNAPSHOT.jar /app/graphql/target/
EXPOSE 8080
CMD ["java", "-jar", "/app/graphql/target/graphql-0.0.1-SNAPSHOT.jar"]

FROM dependencies as debug

RUN apt-get update && apt-get -y upgrade
RUN apt-get install -y inotify-tools dos2unix

EXPOSE 5006

ENTRYPOINT ["./docker-entrypoint.sh"]

docker-compose.yml

  my-service:
    build:
      context: .
      target: debug
    environment:
      - SPRING_PROFILES_ACTIVE=local
    volumes:
      - "~/.m2:/root/.m2"
      - ".:/app"

Upvotes: 0

Related Questions