'spire.pdf in a docker container
I create an application that handle pdf and convert them to pdfa3 and also convert the document onto facturX. I developped my application using Springboot and it works fine. Now i'm trying to dockerize my application. I had issue with database connection and now I meet the following issue
facturx_1  | 2022-03-21 16:20:55.565 ERROR 1 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is class com.spire.ms.System.Exception: No 'Arial' font found!
...
facturx_1  | com.spire.pdf.conversion.PdfStandardsConverter.toPdfA3B(Unknown Source)
facturx_1  | fr.company.app.shared.Utils.loadPdfA3(Utils.java:88)
facturx_1  | fr.company.app.service.impl.FacturXServiceImpl.createFacturX(FacturXServiceImpl.java:75)
facturx_1  | fr.company.app.ui.controller.FacturXController.createFacturXOutoutStream(FacturXController.java:54)
...
facturx_1  | java.base/java.lang.Thread.run(Unknown Source)] with root cause
facturx_1  |
facturx_1  | com.spire.ms.System.Exception: No 'Arial' font found!
facturx_1  |    at com.spire.pdf.packages.sprZOa.spr  (Unknown Source) ~[spire.pdf.free-5.1.0.jar!/:5.1.0]
...
facturx_1  |    at com.spire.pdf.conversion.PdfStandardsConverter.toPdfA3B(Unknown Source) ~[spire.pdf.free-5.1.0.jar!/:5.1.0]
facturx_1  |    at fr.company.app.shared.Utils.loadPdfA3(Utils.java:88) ~[classes!/:0.0.1-SNAPSHOT]
facturx_1  |    at fr.company.app.service.impl.FacturXServiceImpl.createFacturX(FacturXServiceImpl.java:75) ~[classes!/:0.0.1-SNAPSHOT]
facturx_1  |    at fr.company.app.ui.controller.FacturXController.createFacturXOutoutStream(FacturXController.java:54) ~[classes!/:0.0.1-SNAPSHOT]
My code is the following :
public static PDDocument loadPdfA3(String pdfData) {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    byte[] decoded = Base64.getDecoder().decode(pdfData);
    InputStream inputStream = new ByteArrayInputStream(decoded);
    PdfStandardsConverter converter = new PdfStandardsConverter(inputStream);
    converter.toPdfA3B(outputStream);
    byte[] pdfBytes = outputStream.toByteArray();
    InputStream pdfInputStream = new ByteArrayInputStream(pdfBytes);
    try {
        return PDDocument.load(pdfInputStream);
    } catch (IOException e) {
        throw new AppServiceException(e.getLocalizedMessage());
    }
}
the line that returns the exception is the following converter.toPdfA3B(outputStream)
I implementing the following docker file :
# Build stage
FROM maven:3.8.4-openjdk-11 AS build
WORKDIR /app
COPY . /app
RUN mvn clean package -DskipTests
# Package and Run stage
FROM openjdk:11.0.14.1-jre
COPY --from=build app/target/facturx-ws.jar /usr/local/lib/facturx-ws.jar
EXPOSE 8092
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=docker", "/usr/local/lib/facturx-ws.jar"]
Here is also my docker compose:
version: "3"
services:
  facturx:
    container_name: facturx
    image: facturx
    restart: always
    build:
      context: ./
      dockerfile: Dockerfile
    ports:
      - "8081:8080"
    environment:
      MYSQL_HOST: mysqldb
      MYSQL_USER: root
      MYSQL_PASSWORD: root
      MYSQL_PORT: 3306
    #    depends_on:
    #      - mysqldb
    networks:
      - appnetwork
  mysqldb:
    container_name: mysqldb
    image: mysql:8.0.28-oracle
    command: ['mysqld','--character-set-server=utf8','--default-authentication-plugin=mysql_native_password']
    volumes:
      - dbstore:/var/lib/mysql
    ports:
      - "3309:3306"
    environment:
      MYSQL_DATABASE: facturx
      MYSQL_ROOT_PASSWORD: root
    restart: unless-stopped
    networks:
      - appnetwork
volumes:
  dbstore: {}
networks:
  appnetwork:
    driver: bridge
Solution 1:[1]
I changed my Dockerfile :
# Build stage
FROM maven:3.8.4-openjdk-11 AS build
WORKDIR /app
COPY ../../facturx-ws/. /app
COPY ../../facturx-ws/src/main/resources/xsd /app/xsd
RUN mvn clean package -DskipTests
# Package and Run stage
FROM openjdk:11.0.14.1-jre
COPY --from=build app/target/facturx-ws.jar /usr/local/lib/facturx-ws.jar
COPY --from=build app/xsd /usr/local/lib/xsd
#COPY app/facturx-ws/src/main/resources/xsd /usr/local/lib/xsd
RUN echo "ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true" | debconf-set-selections
RUN sed -i'.bak' 's/$/ contrib/' /etc/apt/sources.list
RUN apt-get update; apt-get install -y ttf-mscorefonts-installer fontconfig
RUN fc-cache -f -v
#EXPOSE 8092
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=docker", "/usr/local/lib/facturx-ws.jar"]
I installed windows font by running ttf-mscorefonts-installer
Solution 2:[2]
The exception says: No 'Arial' font found. Be aware that when using spire.pdf to convert a pdf file on a non-windows system, you need to ensure all used fonts in the file are installed, otherwise your application might throw such exception. Here is a similar post on spire forum.
Solution 3:[3]
Thanks davidvera for your answer.
Tested below with e-iceblue:spire.pdf.free:4.4.1 and e-iceblue:spire.pdf.free:5.1.0
In our case the solution was for the Issues we had:
- Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.spire.doc.packages...
- com.spire.ms.System.Exception: No 'Arial' font found!
- "Neutral cultures cannot be used in formatting and parsing and therefore cannot be set as the thread's current culture"
| change | impact | 
|---|---|
| Used JDK instead of JRE | fixed classloading issues (your issue outlined above did not appear) | 
| Used debian instead of alpine (as base) | unknown | 
| Installed msttcorefonts | no missing Arial issue | 
| Ensure to set locale via Locale.setDefault(Locale.ROOT); | Get rid of issue the cultural issue ;) | 
Knowing that this is not a lightweight docker image anymore, but it works we used the following Dockerfile.
FROM openjdk:11-jdk
RUN echo "update packages" && apt update && \
  echo "install ms fonts" && \
    sed -i'.bak' 's/$/ contrib/' /etc/apt/sources.list && \
    apt update && \
    apt install -y ttf-mscorefonts-installer fontconfig && \
    fc-cache -f -v
// add other application files
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | davidvera | 
| Solution 2 | Dheeraj Malik | 
| Solution 3 | 
