mediocre man
mediocre man

Reputation: 125

Minimal JRE gets PDFBOX 3.0.1 Loader Exception - What Module is Missing

I am getting the following exception for PDFBOX 3.0.1:

java.lang.ExceptionInInitializerError at org.apache.pdfbox.Loader.loadPDF(Loader.java:369)

I only get this when running on a Minimal JRE with the following Modules:

 .\jlink --output jre-17.0.6 --compress=2 --no-header-files --no-man-pages --module-path ../jmods --add-modules java.base,java.compiler,java.datatransfer,java.desktop,java.instrument,java.logging,java.management,java.management.rmi,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.se,java.security.jgss,java.security.sasl,java.smartcardio,java.sql,java.sql.rowset,java.transaction.xa,java.xml,java.xml.crypto,jdk.localedata,jdk.crypto.ec

java.base,java.compiler,java.datatransfer,java.desktop,java.instrument,java.logging,java.management,java.management.rmi,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.se,java.security.jgss,java.security.sasl,java.smartcardio,java.sql,java.sql.rowset,java.transaction.xa,java.xml,java.xml.crypto,jdk.localedata,jdk.crypto.ec

It runs fine on the Full versions of Open JDK 11, Open JDK 17, Oracle JRE 8

I can't figure out what module I am missing. According to jdeps pdfbox pdfbox-io and all the libraries only require java.base, java.desktop and java.xml

This is some typical code that produces the error (it has been edited a bit):

 public static boolean isEncrypted(File file) throws IOException
 {
    boolean result;
    try (RandomAccessReadBufferedFile rar = new RandomAccessReadBufferedFile(file)) 
    {
        result = isEncrypted(rar);
    }
    return result;
 }

 public static boolean isEncrypted(RandomAccessRead rar) throws IOException
 {
    boolean encrypted = false;
     
    
    try(PDDocument doc = Loader.loadPDF(rar)) 
    {
        if(doc.isEncrypted())
            encrypted=true;
    }       
    return encrypted;
 }

Don't get too caught up with the code. The point is that everything works fine on a Full JRE but Fails on my Minimal JRE.

Any suggestions would be greatly appreciated.

==== Edit =====

If I include jdk.unsupported then it works fine; but, that is way too big. I noticed that when it works sun.misc.unsafe comes up in the class log with -XX:DumpLoadedClassList=classes2.lst It does not come up when it does not work. I am suspecting that something that is no longer supported is being used in PDFBOX 3.0.1 It may be that it is supported in Java 8 but not Java 9 and above. I went and tested with all the other modules and only jdk.unsupported works (Using JDK 17.0.6+10)

It is possible the issues is with IOUtils in commons-io-2.15.1

Upvotes: 1

Views: 121

Answers (1)

mediocre man
mediocre man

Reputation: 125

The answer is jdk.unsupported was missing.

For some reason I misread the Size of the Minimal JRE and thought it was huge with this module. Actually, jdk.unsupported is very small. I think commons-io-2.15.1 or commons-logging is using sun.misc.unsafe and that is why it is required. But, I could be wrong.

The resulting minimal build command is:

.\jlink --output jre-17.0.6 --compress=2 --no-header-files --no-man-pages --module-path ../jmods --add-modules java.base,java.compiler,java.datatransfer,java.desktop,java.instrument,java.logging,java.management,java.management.rmi,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.se,java.security.jgss,java.security.sasl,java.smartcardio,java.sql,java.sql.rowset,java.transaction.xa,java.xml,java.xml.crypto,jdk.localedata,jdk.crypto.ec,jdk.unsupported

and it comes out to be about 60.5 MB for jre-17.0.6

Upvotes: 1

Related Questions