Hi Tilman,

I tested
https://repository.apache.org/content/groups/snapshots/org/apache/pdfbox/pdfbox-app/3.0.8-SNAPSHOT/
and
confirmed it fixes our case. The actual non-rendering use (metadata +
attachment embedding, load + save) now works in a GraalVM native image
built with stock GraalVM that has no AWT support, on both Linux (GraalVM CE
25.0.2) and macOS (Oracle GraalVM 25.0.2).

I haven’t tested any rendering-related paths, but I’ll let you know if we
run into another non-rendering case that still pulls in AWT.

Thanks again for the quick fix!

Best,
Wanling

On Thu, Jul 2, 2026 at 5:11 AM Tilman Hausherr <[email protected]> wrote:

> Thank you, fixed in
> https://issues.apache.org/jira/browse/PDFBOX-6214
>
> please try with a snapshot
>
> https://repository.apache.org/content/groups/snapshots/org/apache/pdfbox/pdfbox-app/3.0.8-SNAPSHOT/
>
> and tell us whether it works. It might still fail later because pdfbox
> uses some awt classes when when not rendering.
>
> Tilman
>
>
> On 2026/06/30 23:35:32 Wanling Fu wrote:
> > Hi all,
> >
> > I'm using PDFBox in a GraalVM native-image CLI that only does
> non-rendering
> > work: reading metadata and embedding an attachment. It never renders
> pages
> > or touches images. I'd appreciate your advice on a small robustness
> > question rather than reporting it as an outright bug.
> >
> > org.apache.pdfbox.pdmodel.PDDocument has a static initializer that
> eagerly
> > warms up the RGB color subsystem:
> >
> >     /* avoid concurrency issues with PDDeviceRGB */
> >     static {
> >         try {
> >             WritableRaster raster = Raster.createBandedRaster(
> >                     DataBuffer.TYPE_BYTE, 1, 1, 3, new Point(0, 0));
> >             PDDeviceRGB.INSTANCE.toRGBImage(raster);
> >         } catch (IOException ex) {
> >             LOG.debug("voodoo error", ex);
> >         }
> >     }
> >
> > I understand the intent: avoiding a first-use concurrency race in color
> > management. The eager warm-up itself seems reasonable.
> >
> > The problem is the failure mode. The block only catches IOException. If
> AWT
> > native libraries cannot be loaded, the warm-up throws
> UnsatisfiedLinkError
> > instead. That is an Error, so it is not caught. As a result, PDDocument
> > class initialization fails with ExceptionInInitializerError, and
> PDDocument
> > becomes unusable even for operations that do not need rendering or color
> > conversion.
> >
> > Minimal reproducer:
> >
> >     //DEPS org.apache.pdfbox:pdfbox:3.0.7
> >
> >     import java.io.File;
> >
> >     import org.apache.pdfbox.Loader;
> >     import org.apache.pdfbox.pdmodel.PDDocument;
> >
> >     public class PdfBoxMwe {
> >         public static void main(String[] args) throws Exception {
> >             try (PDDocument doc = Loader.loadPDF(new File(args[0]))) {
> >                 System.out.println("pages: " + doc.getNumberOfPages());
> >             }
> >         }
> >     }
> >
> > This works on a normal JVM. It fails when built as a GraalVM native image
> > where the AWT native libraries are unavailable or not loadable.
> >
> > Stack excerpt, using PDFBox 3.0.7, JDK 25, GraalVM/Liberica NIK native
> > image, macOS arm64:
> >
> >     java.lang.UnsatisfiedLinkError: Can't load library:
> > .../libawt_lwawt.dylib
> >         at java.awt.image.ColorModel.loadLibraries(ColorModel.java:208)
> >         at java.awt.image.ColorModel.<clinit>(ColorModel.java:215)
> >         at java.awt.image.Raster.<clinit>(Raster.java:172)
> >         at
> > org.apache.pdfbox.pdmodel.PDDocument.<clinit>(PDDocument.java:103)
> >         at org.apache.pdfbox.Loader.loadPDF(Loader.java:...)
> >         ...
> >
> > Note: this is not strictly macOS-specific. A similar failure also occurs
> on
> > Linux with GraalVM CE, where the AWT native libraries are not bundled.
> The
> > symptom is different there (NoClassDefFoundError:
> > java.awt.GraphicsEnvironment), but it comes from the same
> > PDDocument.<clinit> path. It works on Linux only when the toolchain
> bundles
> > AWT (e.g. Liberica NIK).
> >
> > The specific PDF does not matter. The failure happens in PDDocument's
> > static initializer, before any document content is parsed. Even new
> > PDDocument() can trigger it.
> >
> > My question: would it be reasonable to broaden the catch in that static
> > block, for example by catching LinkageError or Throwable, logging it, and
> > continuing? The warm-up would still run where available. Environments
> > without AWT would skip it, leaving PDDocument usable for non-rendering
> > operations such as parsing, metadata, and attachments. Rendering or color
> > conversion could still fail later when actually used.
> >
> > I searched first: PDFBOX-4746
> > <https://issues.apache.org/jira/browse/PDFBOX-4746> looks related but
> is a
> > different build-time native-image issue. There is also related GraalVM
> > context <https://github.com/oracle/graal/issues/13272> about macOS AWT
> > support in native-image (oracle/graal#13272).
> >
> > Happy to open a JIRA enhancement and/or submit a PR if this direction
> > sounds acceptable.
> >
> > Thanks for the great library.
> >
> > Best regards,
> > Wanling
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>

Reply via email to