Error when Using Aspose PDF Conversion library in Linux Docker Image

Hi GroupDocs Team,

I am using the GroupDocs Conversion library in my linux docker image to convert the docx files to PDF and I am facing the below error / exception

RootCause: java.lang.RuntimeException: Fontconfig head is null, check your fonts or fonts configuration || StackTrace: class com.groupdocs.conversion.internal.c.a.ms.System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> java.lang.reflect.InvocationTargetException
   --- End of inner exception stack trace ---
com.groupdocs.conversion.internal.c.a.ms.System.Reflection.b.N(Unknown Source)
com.groupdocs.conversion.internal.c.a.ms.System.Reflection.b.invoke(Unknown Source)
com.groupdocs.conversion.internal.c.a.ms.System.Reflection.ConstructorInfo.invoke(Unknown Source)
com.groupdocs.conversion.internal.c.a.ms.System.Activator.createInstance(Unknown Source)
com.groupdocs.conversion.loading.DocumentLoaderFactory.getLoader(Unknown Source)
com.groupdocs.conversion.converting.operations.ConversionOperationHelpers.convertToTarget(Unknown Source)
com.groupdocs.conversion.converting.operations.ToPdfConversionOperation.execute(Unknown Source)
com.groupdocs.conversion.converting.operations.ConvertToPdfIfRequiredFromPdfOptionsOperation.execute(Unknown Source)
com.groupdocs.conversion.pipeline.f$1$1.a(Unknown Source)
com.groupdocs.conversion.converting.operations.PagesLimitOperation.execute(Unknown Source)
com.groupdocs.conversion.pipeline.f$1$1.a(Unknown Source)
com.groupdocs.conversion.converting.operations.RemoveCommentsOperation.execute(Unknown Source)
com.groupdocs.conversion.pipeline.f$1$1.a(Unknown Source)
com.groupdocs.conversion.converting.operations.PreProcessWordProcessingDocumentOperation.execute(Unknown Source)
com.groupdocs.conversion.pipeline.f$1$1.a(Unknown Source)
com.groupdocs.conversion.pipeline.e.execute(Unknown Source)
com.groupdocs.conversion.pipeline.h.a(Unknown Source)
com.groupdocs.conversion.pipeline.h.a(Unknown Source)
com.groupdocs.conversion.b.convert(Unknown Source)
com.groupdocs.conversion.Converter.convert(Unknown Source)
com.groupdocs.conversion.Converter.convert(Unknown Source)

java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base/java.lang.reflect.Method.invoke(Method.java:568)
org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:169)
org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:119)
org.springframework.kafka.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:56)
org.springframework.kafka.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:356)
org.springframework.kafka.listener.adapter.RecordMessagingMessageListenerAdapter.onMessage(RecordMessagingMessageListenerAdapter.java:92)
org.springframework.kafka.listener.adapter.RecordMessagingMessageListenerAdapter.onMessage(RecordMessagingMessageListenerAdapter.java:53)
com.sfdc.industries.clm.pdfconversion.config.KafkaConfiguration.lambda$parallelKafkaConsumerRunner$0(KafkaConfiguration.java:103)
io.confluent.parallelconsumer.internal.UserFunctions.carefullyRun(UserFunctions.java:61)
io.confluent.parallelconsumer.ParallelEoSStreamProcessor.lambda$poll$0(ParallelEoSStreamProcessor.java:54)
io.confluent.parallelconsumer.internal.AbstractParallelEoSStreamProcessor.lambda$runUserFunctionInternal$15(AbstractParallelEoSStreamProcessor.java:1346)
io.micrometer.core.instrument.composite.CompositeTimer.record(CompositeTimer.java:69)
io.confluent.parallelconsumer.internal.AbstractParallelEoSStreamProcessor.runUserFunctionInternal(AbstractParallelEoSStreamProcessor.java:1346)
io.confluent.parallelconsumer.internal.AbstractParallelEoSStreamProcessor.runUserFunction(AbstractParallelEoSStreamProcessor.java:1299)
io.confluent.parallelconsumer.internal.AbstractParallelEoSStreamProcessor.lambda$submitWorkToPoolInner$13(AbstractParallelEoSStreamProcessor.java:987)
java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
java.base/java.lang.Thread.run(Thread.java:840)
	at com.groupdocs.conversion.internal.c.a.ms.System.Reflection.b.N(Unknown Source)
	at com.groupdocs.conversion.internal.c.a.ms.System.Reflection.b.invoke(Unknown Source)
	at com.groupdocs.conversion.internal.c.a.ms.System.Reflection.ConstructorInfo.invoke(Unknown Source)
	at com.groupdocs.conversion.internal.c.a.ms.System.Activator.createInstance(Unknown Source)
	at com.groupdocs.conversion.loading.DocumentLoaderFactory.getLoader(Unknown Source)
	at com.groupdocs.conversion.converting.operations.ConversionOperationHelpers.convertToTarget(Unknown Source)
	at com.groupdocs.conversion.converting.operations.ToPdfConversionOperation.execute(Unknown Source)
	at com.groupdocs.conversion.converting.operations.ConvertToPdfIfRequiredFromPdfOptionsOperation.execute(Unknown Source)
	at com.groupdocs.conversion.pipeline.f$1$1.a(Unknown Source)
	at com.groupdocs.conversion.converting.operations.PagesLimitOperation.execute(Unknown Source)
	at com.groupdocs.conversion.pipeline.f$1$1.a(Unknown Source)
	at com.groupdocs.conversion.converting.operations.RemoveCommentsOperation.execute(Unknown Source)
	at com.groupdocs.conversion.pipeline.f$1$1.a(Unknown Source)
	at com.groupdocs.conversion.converting.operations.PreProcessWordProcessingDocumentOperation.execute(Unknown Source)
	at com.groupdocs.conversion.pipeline.f$1$1.a(Unknown Source)
	at com.groupdocs.conversion.pipeline.e.execute(Unknown Source)
	at com.groupdocs.conversion.pipeline.h.a(Unknown Source)
	at com.groupdocs.conversion.pipeline.h.a(Unknown Source)
	at com.groupdocs.conversion.b.convert(Unknown Source)
	at com.groupdocs.conversion.Converter.convert(Unknown Source)
	at com.groupdocs.conversion.Converter.convert(Unknown Source)

	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:169)
	at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:119)
	at org.springframework.kafka.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:56)
	at org.springframework.kafka.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:356)
	at org.springframework.kafka.listener.adapter.RecordMessagingMessageListenerAdapter.onMessage(RecordMessagingMessageListenerAdapter.java:92)
	at org.springframework.kafka.listener.adapter.RecordMessagingMessageListenerAdapter.onMessage(RecordMessagingMessageListenerAdapter.java:53)
	at com.sfdc.industries.clm.pdfconversion.config.KafkaConfiguration.lambda$parallelKafkaConsumerRunner$0(KafkaConfiguration.java:103)
	at io.confluent.parallelconsumer.internal.UserFunctions.carefullyRun(UserFunctions.java:61)
	at io.confluent.parallelconsumer.ParallelEoSStreamProcessor.lambda$poll$0(ParallelEoSStreamProcessor.java:54)
	at io.confluent.parallelconsumer.internal.AbstractParallelEoSStreamProcessor.lambda$runUserFunctionInternal$15(AbstractParallelEoSStreamProcessor.java:1346)
	at io.micrometer.core.instrument.composite.CompositeTimer.record(CompositeTimer.java:69)
	at io.confluent.parallelconsumer.internal.AbstractParallelEoSStreamProcessor.runUserFunctionInternal(AbstractParallelEoSStreamProcessor.java:1346)
	at io.confluent.parallelconsumer.internal.AbstractParallelEoSStreamProcessor.runUserFunction(AbstractParallelEoSStreamProcessor.java:1299)
	at io.confluent.parallelconsumer.internal.AbstractParallelEoSStreamProcessor.lambda$submitWorkToPoolInner$13(AbstractParallelEoSStreamProcessor.java:987)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
	... 46 more
Caused by: java.lang.InternalError: java.lang.reflect.InvocationTargetException
	at java.desktop/sun.font.FontManagerFactory$1.run(FontManagerFactory.java:87)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
	at java.desktop/sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:75)
	at java.desktop/sun.java2d.SunGraphicsEnvironment.getFontManagerForSGE(SunGraphicsEnvironment.java:137)
	at java.desktop/sun.java2d.SunGraphicsEnvironment.getAllFonts(SunGraphicsEnvironment.java:156)
	at java.desktop/sun.java2d.HeadlessGraphicsEnvironment.getAllFonts(HeadlessGraphicsEnvironment.java:76)
	at com.groupdocs.conversion.internal.c.a.pd.internal.l6h.l0v.lv(Unknown Source)
	at com.groupdocs.conversion.internal.c.a.pd.internal.l6h.l0v.<init>(Unknown Source)
	at com.groupdocs.conversion.internal.c.a.pd.internal.l6h.l0v.<init>(Unknown Source)
	at com.groupdocs.conversion.internal.c.a.pd.internal.l6h.l0v$2.lwI(Unknown Source)
	at com.groupdocs.conversion.internal.c.a.pd.internal.l6h.l0v$2.lf(Unknown Source)
	at com.groupdocs.conversion.internal.c.a.pd.internal.l14y.lI.lb(Unknown Source)
	at com.groupdocs.conversion.internal.c.a.pd.internal.l6h.l0v.lj(Unknown Source)
	at com.groupdocs.conversion.internal.c.a.pd.FontRepository.getSources(Unknown Source)
	at com.groupdocs.conversion.utils.common.FontsHelper.setForPdf(Unknown Source)
	at com.groupdocs.conversion.loading.loaders.PdfDocumentLoader.<init>(Unknown Source)
	... 51 more
Caused by: java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
	at java.desktop/sun.font.FontManagerFactory$1.run(FontManagerFactory.java:85)
	... 66 more
Caused by: java.lang.RuntimeException: Fontconfig head is null, check your fonts or fonts configuration
	at java.desktop/sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1271)
	at java.desktop/sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:224)
	at java.desktop/sun.awt.FontConfiguration.init(FontConfiguration.java:106)
	at java.desktop/sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:706)
	at java.desktop/sun.font.SunFontManager$2.run(SunFontManager.java:358)
	at java.desktop/sun.font.SunFontManager$2.run(SunFontManager.java:315)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
	at java.desktop/sun.font.SunFontManager.<init>(SunFontManager.java:315)
	at java.desktop/sun.awt.FcFontManager.<init>(FcFontManager.java:35)
	at java.desktop/sun.awt.X11FontManager.<init>(X11FontManager.java:56)
	... 72 more

Need some help on how to fix this.

hi team,
May you please help resolve this issue at the earliest. Thanks

@amitdash @saravanaprabhusr

Can you please share the sample file, Dockerfile and the code you’re using to reproduce this issue?

Hi @vladimir.litvinchik

package com.example;

import com.groupdocs.conversion.Converter;
import com.groupdocs.conversion.ConverterSettings;
import com.groupdocs.conversion.contracts.ConverterSettingsProvider;
import com.groupdocs.conversion.contracts.documentinfo.IDocumentInfo;
import com.groupdocs.conversion.internal.c.a.w.FolderFontSource;
import com.groupdocs.conversion.internal.c.a.w.FontSourceBase;
import com.groupdocs.conversion.internal.c.a.w.SystemFontSource;
import com.groupdocs.conversion.internal.c.a.w.FontSettings;
import com.groupdocs.conversion.options.convert.PdfConvertOptions;
import com.groupdocs.conversion.options.convert.PdfDocumentInfo;
import com.groupdocs.conversion.options.convert.PdfOptions;
import com.groupdocs.conversion.options.load.WordProcessingLoadOptions;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

import static jdk.xml.internal.SecuritySupport.getClassLoader;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hi");
        String filePath = "templateGDocs.docx"; // Replace with your file path
        String outputFilePath = "output.pdf";
        try {
            // Create a File object
            File file = new File(filePath);


            String userHome = System.getProperty("user.home");
            String outputFilePathString = userHome + File.separator + "outputfile.docx";
            System.out.println(outputFilePathString);
            // Open an InputStream for the file
            try (InputStream inputStream = Main.class.getClassLoader().getResourceAsStream(filePath)) {

                WordProcessingLoadOptions loadOptions = new WordProcessingLoadOptions();
                // Below is required for adding Tags in the output PDF documnet
                loadOptions.setPreserveDocumentStructure(true);

               
                try (Converter converter = new Converter(() -> inputStream, () -> loadOptions)) {
                    try (ByteArrayOutputStream ms = new ByteArrayOutputStream()) {
                        PdfConvertOptions convertOptions = new PdfConvertOptions();
                        PdfOptions pdfOptions = convertOptions.getPdfOptions();
                        pdfOptions.getFormattingOptions().setDisplayDocTitle(true);
                        PdfDocumentInfo pdfDocumentInfo = pdfOptions.getDocumentInfo();
                        pdfDocumentInfo.setTitle("Test");
                        converter.convert(() -> ms, convertOptions);
                        byte[] outputPdfBytes = ms.toByteArray();
                        System.out.println("Generated PDF content size in bytes: " + outputPdfBytes.length);
                        try (FileOutputStream fileOutputStream = new FileOutputStream(outputFilePath)) {
                            fileOutputStream.write(outputPdfBytes);
                            System.out.println("File created successfully!");
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                    throw e;
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

Dockerfile

FROM eclipse-temurin:11-jre-centos7

# Set the working directory in the container
WORKDIR /app

# Copy the JAR file into the container
COPY target/GroupDocs-1.0-SNAPSHOT-jar-with-dependencies.jar /app/GroupDocs-1.0-SNAPSHOT-jar-with-dependencies.jar

# Command to run the JAR file
ENTRYPOINT ["java", "-jar", "GroupDocs-1.0-SNAPSHOT-jar-with-dependencies.jar"]

I am facing a different error when I am using this particular docker image which is
2024-08-21T06:50:20.004244750Z Exception in thread “main” class com.groupdocs.conversion.internal.c.a.pd.exceptions.FontNotFoundException: Font Arial was not found
2024-08-21T06:50:20.004292292Z com.groupdocs.conversion.internal.c.a.pd.FontRepository.findFont(Unknown Source)
2024-08-21T06:50:20.004298500Z com.groupdocs.conversion.converting.operations.watermark.WatermarkPdfOperation.createTextStamp(Unknown Source)
2024-08-21T06:50:20.004300209Z

Please let me know if you need more details.

We are actually using a different base image which is private to us where the above the listed error message is appearing

@saravanaprabhusr

Thank you for sharing the details. We’ll try reproducing this issue and update you.

@saravanaprabhusr @amitdash

I have reproduced this issue locally. The error message: Font Arial was not found was a hint to root cause of this issue. This Docker image does not contain Microsoft fonts: Times, Arial, Verdana etc.

To solve this issue you have a couple of options:

  1. Install Windows fonts using package manager by installing required tools, fonts and as a final step you have to update font cache.
sudo yum install fontconfig cabextract
sudo yum install epel-release
sudo yum install msttcore-fonts-installer
sudo fc-cache -fv
  1. Copy fonts if you have them at hand and update font cache.
sudo cp ./fonts /usr/share/fonts
sudo fc-cache -fv

Please let us know if it works for you.

@vladimir.litvinchik we will not able to install packages because they are not part of our repositories , can you please tell us which fonts are required for groupdocs library to work and from where we can download them , do they have any dependencies? do they have any license implications which we should worry about ? Can you also share docker file which worked for you.

@ankgupta067

When testing this issue I have copied the fonts that I have on my Windows machine.

In case you would like to install the fonts you can check this sample application that includes Dockerfile: conversion-java-cent-os-jar.zip.

# docker build -t groupdocs:conversion-java-centos .
# docker run --rm -it -v ${PWD}/output:/app/output groupdocs:conversion-java-centos

FROM eclipse-temurin:11-jre-centos7

COPY ./CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo

# Install required dependencies
RUN yum install -y epel-release cabextract

# Install Microsoft Core Fonts
RUN yum install -y https://downloads.sourceforge.net/project/mscorefonts2/rpms/msttcore-fonts-installer-2.6-1.noarch.rpm

# Rebuild the font cache
RUN fc-cache -f -v

# Set the working directory in the container
WORKDIR /app

# Copy the JAR file into the container
COPY App.class /app/App.class
COPY groupdocs-conversion-24.7.jar /app/groupdocs-conversion-24.7.jar
COPY sample.docx ./app/sample.docx

# Run the app
ENTRYPOINT ["java", "-cp", ".:./groupdocs-conversion-24.7.jar", "App"]

To install all the dependencies I had to use this SO answer and prepare custom CentOS-Base.repo file

# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client.  You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#

[base]
name=CentOS-$releasever - Base
baseurl=http://vault.centos.org/7.9.2009/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

[updates]
name=CentOS-$releasever - Updates
baseurl=http://vault.centos.org/7.9.2009/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

[extras]
name=CentOS-$releasever - Extras
baseurl=http://vault.centos.org/7.9.2009/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

[centosplus]
name=CentOS-$releasever - Plus
baseurl=http://vault.centos.org/7.9.2009/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

Microsoft fonts are distributed under END-USER LICENSE AGREEMENT FOR
MICROSOFT SOFTWARE
. As far as I know these fonts can be used in documents and distributed as part of them. But, you can’t redistribute fonts separately, meaning you cannot package or sell the fonts themselves. You are free to use them for viewing or generating documents.

thanks @vladimir.litvinchik we will try that , we do copy some open source fonts like
“500”:“Arimo-Regular”,
“500I”:“Arimo-Italic”,
“700”:“Arimo-Bold”,
“700I”:“Arimo-BoldItalic”

Are these not enough for group docs library to work , i want to get a list of font which is required for groupdocs conversion to happen?

@ankgupta067

It depends which fonts are used in the documents. I would recommend installing Microsoft fonts at the first place.

As a second option you can substitute missing fonts with the one that you have, see Specify font substitution documentation topic for substitution missing fonts in Word documents.

@saravanaprabhusr @amitdash @ankgupta067

Can you please clarify if you have managed to fix all of the issues?

@vladimir.litvinchik I was able to get past the previous errors. But now we are stuck at a new error. This also looks like an issue due to fonts. I will attach the errors dump in a file and one more point to add is that this particular error which is occurring in our docker container is not thrown as an error or exception. I think this needs to. be fixed we found this log by using thread dump.

groupdocerror.docx (28.5 KB)

@saravanaprabhusr

May you please clarify which file you’re converting. The Dockerfile and sample app would also help us to be on the same page. Having more details at hand helps us to reproduce and investigate the issue.