javadockerapache-poi

Need help regarding an error in the Dockerized version of the application


I am currently working on an application that uses a Spring Boot-based backend based on Java 17. I use Maven as the build tool. The front end is a ReactJS-based application.

In my developer environment, I use Oracle JDK java 17.0.4. When I build and execute the report functionality of this application it works as expected.

But when the same functionality is checked in a dockerized environment for one Excel report download scenario fails with an error. The back-end log indicates some errors briefly mentioned below.

The error message encountered is a Java UnsatisfiedLinkError related to the libfontmanager.so library and its dependency libfreetype.so.6. This error seems to occur when Java is unable to load a required native library (libfreetype.so.6) that is necessary for the functioning of the Java font system.

How can I resolve this issue on Docker environments? Are any changes required for the docker file or Java version used?

Related docker File

# === Stage 1: Build the Spring Boot app ===
FROM maven:3.6.3-openjdk-17 AS build
WORKDIR /app
COPY pom.xml .
COPY src/ /app/src/
RUN mvn package -DskipTests
# === Stage 2: Create the final Docker image ===
FROM openjdk:17-alpine
WORKDIR /app
COPY --from=build /app/target/backend-0.0.1-SNAPSHOT.jar app.jar
# Set environment variables for MySQL configuration
ENV MYSQL_HOST=localhost
ENV MYSQL_PORT=****** //Omitted
ENV MYSQL_DATABASE=db
ENV MYSQL_USERNAME=****** //Omitted
ENV MYSQL_PASSWORD=************ //Omitted
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]

Brief set error messages are listed below.

2023-10-05T07:19:23.875Z ERROR 1 --- [nio-8080-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed: java.lang.UnsatisfiedLinkError: /opt/openjdk-17/lib/libfontmanager.so: Error loading shared library libfreetype.so.6: No such file or directory (needed by /opt/openjdk-17/lib/libfontmanager.so)] with root cause

java.lang.UnsatisfiedLinkError: /opt/openjdk-17/lib/libfontmanager.so: Error loading shared library libfreetype.so.6: No such file or directory (needed by /opt/openjdk-17/lib/libfontmanager.so)

at java.base/jdk.internal.loader.NativeLibraries.load(Native Method) ~[na:na]
at java.base/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.open(NativeLibraries.java:383) ~[na:na]
at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:227) ~[na:na]
at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:169) ~[na:na]
at java.base/jdk.internal.loader.NativeLibraries.findFromPaths(NativeLibraries.java:310) ~[na:na]
at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:280) ~[na:na]
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2392) ~[na:na]
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:808) ~[na:na]
at java.base/java.lang.System.loadLibrary(System.java:1893) ~[na:na]
at java.desktop/sun.font.FontManagerNativeLibrary$1.run(FontManagerNativeLibrary.java:57) ~[na:na]
at java.base/java.security.AccessController.doPrivileged(AccessController.java:312) ~[na:na]
at java.desktop/sun.font.FontManagerNativeLibrary.<clinit>(FontManagerNativeLibrary.java:32) ~[na:na]
at java.desktop/sun.font.SunFontManager$1.run(SunFontManager.java:270) ~[na:na]
at java.desktop/sun.font.SunFontManager$1.run(SunFontManager.java:268) ~[na:na]
at java.base/java.security.AccessController.doPrivileged(AccessController.java:312) ~[na:na]
at java.desktop/sun.font.SunFontManager.<clinit>(SunFontManager.java:268) ~[na:na]
at java.base/java.lang.Class.forName0(Native Method) ~[na:na]
at java.base/java.lang.Class.forName(Class.java:466) ~[na:na]
at java.desktop/sun.font.FontManagerFactory$1.run(FontManagerFactory.java:82) ~[na:na]
at java.base/java.security.AccessController.doPrivileged(AccessController.java:312) ~[na:na]
at java.desktop/sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74) ~[na:na]
at java.desktop/java.awt.Font.getFont2D(Font.java:526) ~[na:na]
at java.desktop/java.awt.Font.canDisplayUpTo(Font.java:2279) ~[na:na]
at java.desktop/java.awt.font.TextLayout.singleFont(TextLayout.java:469) ~[na:na]
at java.desktop/java.awt.font.TextLayout.<init>(TextLayout.java:530) ~[na:na]
at org.apache.poi.ss.util.SheetUtil.getDefaultCharWidth(SheetUtil.java:285) ~[poi-5.0.0.jar!/:5.0.0]
at org.apache.poi.ss.util.SheetUtil.getColumnWidth(SheetUtil.java:259) ~[poi-5.0.0.jar!/:5.0.0]
at org.apache.poi.ss.util.SheetUtil.getColumnWidth(SheetUtil.java:244) ~[poi-5.0.0.jar!/:5.0.0]
at org.apache.poi.xssf.usermodel.XSSFSheet.autoSizeColumn(XSSFSheet.java:523) ~[poi-ooxml-5.0.0.jar!/:5.0.0]
at org.apache.poi.xssf.usermodel.XSSFSheet.autoSizeColumn(XSSFSheet.java:505) ~[poi-ooxml-5.0.0.jar!/:5.0.0]
at com.antarctica21.backend.forecasting.service.PlanService.saveWOSRZipExcelFile(PlanService.java:3352) ~[classes!/:0.0.1-SNAPSHOT]
at com.antarctica21.backend.forecasting.service.PlanService.getWeekOversSalesExcelDetails(PlanService.java:3244) ~[classes!/:0.0.1-SNAPSHOT] 

java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager

at java.base/java.lang.Class.forName0(Native Method) ~[na:na]
at java.base/java.lang.Class.forName(Class.java:466) ~[na:na]
at java.desktop/sun.font.FontManagerFactory$1.run(FontManagerFactory.java:82) ~[na:na]
at java.base/java.security.AccessController.doPrivileged(AccessController.java:312) ~[na:na]
at java.desktop/sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74) ~[na:na]
at java.desktop/java.awt.Font.getFont2D(Font.java:526) ~[na:na]
at java.desktop/java.awt.Font.canDisplayUpTo(Font.java:2279) ~[na:na]
at java.desktop/java.awt.font.TextLayout.singleFont(TextLayout.java:469) ~[na:na]
at java.desktop/java.awt.font.TextLayout.<init>(TextLayout.java:530) ~[na:na]
at org.apache.poi.ss.util.SheetUtil.getDefaultCharWidth(SheetUtil.java:285) ~[poi-5.0.0.jar!/:5.0.0]
at org.apache.poi.ss.util.SheetUtil.getColumnWidth(SheetUtil.java:259) ~[poi-5.0.0.jar!/:5.0.0]
at org.apache.poi.ss.util.SheetUtil.getColumnWidth(SheetUtil.java:244) ~[poi-5.0.0.jar!/:5.0.0]
at org.apache.poi.xssf.usermodel.XSSFSheet.autoSizeColumn(XSSFSheet.java:523) ~[poi-ooxml-5.0.0.jar!/:5.0.0]
at org.apache.poi.xssf.usermodel.XSSFSheet.autoSizeColumn(XSSFSheet.java:505) ~[poi-ooxml-5.0.0.jar!/:5.0.0]
at com.antarctica21.backend.forecasting.service.PlanService.saveWOSRZipExcelFile(PlanService.java:3352) ~[classes!/:0.0.1-SNAPSHOT]
at com.antarctica21.backend.forecasting.service.PlanService.getWeekOversSalesExcelDetails(PlanService.java:3244) ~[classes!/:0.0.1-SNAPSHOT]
at com.antarctica21.backend.forecasting.service.PlanService.getWeekOversSalesExcelDetilsByCriteria(PlanService.java:541) ~[classes!/:0.0.1-SNAPSHOT]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) ~[spring-aop-6.0.7.jar!/:6.0.7]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698) ~[spring-aop-6.0.7.jar!/:6.0.7]
at com.antarctica21.backend.forecasting.service.PlanService$$SpringCGLIB$$0.getWeekOversSalesExcelDetilsByCriteria(<generated>) ~[classes!/:0.0.1-SNAPSHOT]
at com.antarctica21.backend.forecasting.controller.PlanController.getWeekOversSalesExcelDetilsByCriteria(PlanController.java:190) ~[classes!/:0.0.1-SNAPSHOT]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]

Update on Issue Updated the docker file to handle the error identified due to Openjdk image limitation as suggested in below mentioned comments

To install the required packages (freetype and fontconfig) the Dockerfile was updated as follows:

# Install required libraries
    RUN apk add --no-cache freetype fontconfig

I also updated the Apache POI dependencies to the latest versions as suggested.

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.4</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.4</version>
</dependency>

Update on Issue 2 When the above-mentioned updates were made to the Docker file, the existing error was fixed but another issue was displayed due to font-related limitations.

java. lang.NullPointerException: Cannot load from short array because "sun.awt.FontConfiguration.head" is null.

Updated the Docker file as mentioned below and the were resolved.

RUN apk add --no-cache msttcorefonts-installer fontconfig
RUN update-ms-fonts

Solution

  • As suggested in the above comments by @OneCricketeer and @Pino I updated the docker file to handle the error identified due to Openjdk image limitation.

    To install the required packages (freetype and fontconfig) the Dockerfile was updated as follows:

     # Install required libraries
            RUN apk add --no-cache freetype fontconfig
    

    I also updated the Apache POI dependencies to the latest versions as suggested by @OneCricketeer

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.4</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.4</version>
    </dependency>
    

    When the above-mentioned updates were made to the Docker file and pom.xml, the existing error was fixed but another issue was displayed due to the same font-related limitation.

    java. lang.NullPointerException: Cannot load from short array because "sun.awt.FontConfiguration.head" is null.
    

    I updated the Docker file as mentioned below and they were resolved.

    RUN apk add --no-cache msttcorefonts-installer fontconfig
    RUN update-ms-fonts
    

    Resource