Search code examples
javadockermapstruct

ClassNotFound org.mapstruct.factory.Mappers in Docker Image


I am using Mapstruct (with lombok), and Mapstruct fails when I dockerize the app after calling an endpoint which uses MapStruct to map a DTO to entity.

Caused by: java.lang.ClassNotFoundException: org.mapstruct.factory.Mappers at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:435) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589) at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)

Everything works well when I run the app locally, but dockerizing the app makes Mapstruct fail.

Dockerfile:

FROM openjdk:15-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

Dependencies and docker plugin in build.gradle:


docker {
    dependsOn build as Task
    name "${project.group}/${jar.baseName}"
    files bootJar.archivePath
    buildArgs(['JAR_FILE': "${bootJar.archiveName}"])
}

dependencies {
    .....

    compileOnly 'org.mapstruct:mapstruct:1.4.1.Final'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.1.Final'
}

Is there something I am missing or I need to do additionally to have Impl classes in the docker?


Solution

  • I do not know much about how you are creating your docker image. However, I believe that the problem is that you are using compileOnly for the mapstruct dependency (where the Mappers factory is located).

    I think that compileOnly is no longer encouraged to be used and it was never a correct one for org.mapstruct:mapstruct anyways. If you are using the default component model for your mappers and you want to use the Mappers factory then the org.mapstruct:mapstruct dependency is most definitely not compileOnly. You'll need to change that for your docker image to work correctly.