I'm trying to generate a PDF in my Quarkus application using https://github.com/LibrePDF/OpenPDF. Locally everything works fine, but after building the application I get the following exception:
2023-11-20 08:32:57,631 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (vert.x-eventloop-thread-1) HTTP Request to /api/v1/xxx/xxx failed, error id: 87b2b3dc-20d7-47fe-9185-ad552db16f1d-1: com.lowagie.text.DocumentException: java.lang.RuntimeException: java.io.IOException: font-fallback/LiberationSans-Regular.ttf not found as file or resource.
at com.lowagie.text.pdf.PdfDocument.add(PdfDocument.java:805)
at com.lowagie.text.Document.add(Document.java:303)
at xxx.pdf.xxx.addSpacer(xxx.java:54)
at xxx.xxx.service.xxx.generatePdf(xxx.java:20)
at xxx.xxx.service.xxx_ClientProxy.generatePdf(Unknown Source)
at xxx.xxx.web.xxxResource.xxx(xxxResource.java:34)
at xxx.xxx.web.xxxResource_Subclass.xxx$$superforward(Unknown Source)
at xxx.xxx.web.xxxResource_Subclass$$function$$1.apply(Unknown Source)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:73)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:62)
at io.quarkus.hibernate.validator.runtime.interceptor.AbstractMethodValidationInterceptor.validateMethodInvocation(AbstractMethodValidationInterceptor.java:71)
at io.quarkus.hibernate.validator.runtime.jaxrs.ResteasyReactiveEndPointValidationInterceptor.validateMethodInvocation(ResteasyReactiveEndPointValidationInterceptor.java:21)
at io.quarkus.hibernate.validator.runtime.jaxrs.ResteasyReactiveEndPointValidationInterceptor_Bean.intercept(Unknown Source)
at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:30)
at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:27)
at xxx.xxx.web.xxxResource_Subclass.xxx(Unknown Source)
at xxx.xxx.web.xxxResource_ClientProxy.xxx(Unknown Source)
at xxx.xxx.web.xxxResource$quarkusrestinvoker$xxx_c98f2d898847d04b7d6c830b00f74b3f28a237fa.invoke(Unknown Source)
at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:145)
at org.jboss.resteasy.reactive.server.vertx.VertxResteasyReactiveRequestContext$1$1.handle(VertxResteasyReactiveRequestContext.java:78)
at org.jboss.resteasy.reactive.server.vertx.VertxResteasyReactiveRequestContext$1$1.handle(VertxResteasyReactiveRequestContext.java:75)
at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:264)
at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:246)
at io.vertx.core.impl.EventLoopContext.lambda$runOnContext$0(EventLoopContext.java:43)
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at [email protected]/java.lang.Thread.run(Thread.java:833)
at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:807)
at org.graalvm.nativeimage.builder/com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:210)
Suppressed: ExceptionConverter: java.io.IOException: The document has no pages.
Caused by: java.lang.RuntimeException: java.io.IOException: font-fallback/LiberationSans-Regular.ttf not found as file or resource.
at com.lowagie.text.pdf.PdfChunk.<init>(PdfChunk.java:222)
at com.lowagie.text.pdf.PdfDocument.add(PdfDocument.java:477)
... 36 more
Caused by: java.io.IOException: font-fallback/LiberationSans-Regular.ttf not found as file or resource.
at com.lowagie.text.pdf.RandomAccessFileOrArray.<init>(RandomAccessFileOrArray.java:117)
at com.lowagie.text.pdf.TrueTypeFont.process(TrueTypeFont.java:641)
at com.lowagie.text.pdf.TrueTypeFontUnicode.<init>(TrueTypeFontUnicode.java:104)
at com.lowagie.text.pdf.BaseFont.createFont(BaseFont.java:850)
at com.lowagie.text.pdf.BaseFont.createFont(BaseFont.java:738)
at com.lowagie.text.pdf.BaseFont.createFont(BaseFont.java:516)
at com.lowagie.text.pdf.PdfChunk.<init>(PdfChunk.java:219)
... 37 more
The library uses Liberation Sans as a fallback/default font for a lot of non-text symbols. Instead of using the preinstalled font, it generates it's own font object from a static resource inside the library (font-fallback/LiberationSans-Regular.ttf). This file isn't included in the build process and therefore can't be found after the native build.
Is there a way to include resources of a dependency? Including resources in quarkus is described here https://quarkus.io/guides/writing-native-applications-tips#including-resources, but imo this can only be used to include project-owned resources.