I am trying to figure out how to use PDFBox (2.0.30) to render image from a PDF document in a native application based on Spring Boot (3.2.1).
PDF generation works fine, but image rendering fails. when I try to convert a PDocument
into an image using the PDFRenderer#renderImage(int, float)
, there is the following error:
java.lang.NoSuchFieldError: sun.java2d.pipe.ShapeSpanIterator.pData
at org.graalvm.nativeimage.builder/com.oracle.svm.core.jni.functions.JNIFunctions$Support.getFieldID(JNIFunctions.java:1357) ~[na:na]
at org.graalvm.nativeimage.builder/com.oracle.svm.core.jni.functions.JNIFunctions.GetFieldID(JNIFunctions.java:449) ~[na:na]
at [email protected]/sun.java2d.pipe.ShapeSpanIterator.initIDs(Native Method) ~[na:na]
at [email protected]/sun.java2d.pipe.ShapeSpanIterator.<clinit>(ShapeSpanIterator.java:71) ~[na:na]
at [email protected]/sun.java2d.pipe.LoopPipe.getFillSSI(LoopPipe.java:228) ~[na:na]
at [email protected]/sun.java2d.SunGraphics2D.validateCompClip(SunGraphics2D.java:1911) ~[na:na]
at [email protected]/sun.java2d.SunGraphics2D.setClip(SunGraphics2D.java:2046) ~[na:na]
at org.apache.pdfbox.rendering.PageDrawer.transferClip(PageDrawer.java:440) ~[na:na]
at org.apache.pdfbox.rendering.PageDrawer.setClip(PageDrawer.java:411) ~[na:na]
at org.apache.pdfbox.rendering.PageDrawer.beginText(PageDrawer.java:447) ~[na:na]
at org.apache.pdfbox.contentstream.operator.text.BeginText.process(BeginText.java:41) ~[na:na]
at org.apache.pdfbox.contentstream.PDFStreamEngine.processOperator(PDFStreamEngine.java:958) ~[awt-native-test:2.0.30]
at org.apache.pdfbox.contentstream.PDFStreamEngine.processStreamOperators(PDFStreamEngine.java:531) ~[awt-native-test:2.0.30]
at org.apache.pdfbox.contentstream.PDFStreamEngine.processStream(PDFStreamEngine.java:506) ~[awt-native-test:2.0.30]
at org.apache.pdfbox.contentstream.PDFStreamEngine.processPage(PDFStreamEngine.java:150) ~[awt-native-test:2.0.30]
at org.apache.pdfbox.rendering.PageDrawer.drawPage(PageDrawer.java:288) ~[na:na]
at org.apache.pdfbox.rendering.PDFRenderer.renderImage(PDFRenderer.java:355) ~[na:na]
at org.apache.pdfbox.rendering.PDFRenderer.renderImage(PDFRenderer.java:272) ~[na:na]
at org.apache.pdfbox.rendering.PDFRenderer.renderImage(PDFRenderer.java:232) ~[na:na]
at com.vialink.awtnativetest.PDFService.toImage(PDFService.java:37) ~[awt-native-test:na]
...
The Spring Webflux Application (awt-native-test) is a native executable built with the Native Maven Plugin:
mvn native:compose -Pnative
To run it:
./target/awt-native-test
Java Version:
openjdk version "21.0.1" 2023-10-17 LTS
OpenJDK Runtime Environment Liberica-NIK-23.1.1-1 (build 21.0.1+12-LTS)
OpenJDK 64-Bit Server VM Liberica-NIK-23.1.1-1 (build 21.0.1+12-LTS, mixed mode, sharing)
I guess I have to declare several runtime hints for Java2D to use PDFBox (something like hints.jni().registerType(ShapeSpanIterator.class, MemberCategory.values());
), however I do not known how to do it as sun.java2D.pipe
code is not exported by the module.
What am I missing ? Is image rendering from PDFBox native-ready ?
Code to reproduce my problem is here: https://github.com/nicolasjanet/awt-native-test
I ran my app using the tracing agent to get the missing hints, and I end up adding these hints using TypeReference
in my RuntimeHintsRegistrar
implementation:
// Java2D
hints.jni().registerType(TypeReference.of("sun.java2d.pipe.ShapeSpanIterator"), MemberCategory.values());
// JPEG
hints.jni().registerType(TypeReference.of("sun.awt.image.ByteComponentRaster"), MemberCategory.values());
hints.jni().registerType(TypeReference.of("com.sun.imageio.plugins.jpeg.JPEGImageWriter"), MemberCategory.values());
hints.jni().registerType(JPEGQTable.class, MemberCategory.values());
hints.jni().registerType(JPEGHuffmanTable.class, MemberCategory.values());