我正在尝试弄清楚如何使用 PDFBox (2.0.30) 在基于 Spring Boot (3.2.1) 的本机应用程序中渲染 PDF 文档中的图像。
PDF 生成工作正常,但图像渲染失败。当我尝试使用
PDocument
将 PDFRenderer#renderImage(int, float)
转换为图像时,出现以下错误:
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]
...
Spring Webflux 应用程序 (awt-native-test) 是使用本机 Maven 插件构建的本机可执行文件:
mvn native:compose -Pnative
运行它:
./target/awt-native-test
Java版本:
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)
我想我必须为 Java2D 声明几个运行时提示才能使用 PDFBox(类似于
hints.jni().registerType(ShapeSpanIterator.class, MemberCategory.values());
),但是我不知道如何做到这一点,因为 sun.java2D.pipe
代码不是由模块导出的。
我错过了什么? PDFBox 的图像渲染是本机就绪的吗?
重现我的问题的代码在这里:https://github.com/nicolasjanet/awt-native-test
我使用跟踪代理运行我的应用程序来获取丢失的提示,最后我在我的
TypeReference
实现中使用 RuntimeHintsRegistrar
添加这些提示:
// 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());