'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 |