Aspose.Words with Java throws InvocationTargetException due to limitation of JAI with Java 11

Hi,

I use Aspose.Words in order to edit and then convert a .docx file to pdf file format. These files may contain JPG images. In some cases(depending on the image inside the .docx document) I get the following messages in my application logs:

Aspose.Words for Java is limited with JDK's built-in image encoders/decoders.
In order to improve reading/writing quality use the following external graphics libraries:
* ImageMagick
   - Download and install ImageMagick from https://imagemagick.org/script/download.php
   - Windows users will have to set up the path to ImageMagick via IM4JAVA_TOOLPATH or ProcessStarter.setGlobalSearchPath(myPath), e.g. IM4JAVA_TOOLPATH=C:\Program Files\ImageMagick-7.0.8-Q16
   - Download im4java https://sourceforge.net/projects/im4java/files/
   - Copy im4java-1.4.0.jar to CLASSPATH or copy to JDK_HOME/jre/lib/ext directory.
* Java Advanced Imaging API
   - Download jai_codec and add it to application classpath https://mvnrepository.com/artifact/javax.media/jai_codec/1.1.3
   - Download jai_core and add it to application classpath https://mvnrepository.com/artifact/javax.media/jai-core/1.1.3
   - Download jai_imageio and add it to application classpath https://mvnrepository.com/artifact/javax.media/jai_imageio/1.1.1

I installed ImageMagick and I added the Java Advanced Imaging API required jars in my application’s classpath. Now I don’t get this message. However, when I try to convert a .docx file to .pdf I get the following stacktrace:

Preformatted textError: One factory fails for the operation "jpeg"
Occurs in: javax.media.jai.ThreadSafeOperationRegistry
java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
.
.
.
Caused by: javax.media.jai.util.ImagingException: All factories fail for the operation "jpeg"
	at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1687)
	at javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
	at javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
	at com.sun.media.jai.opimage.StreamRIF.create(StreamRIF.java:102)
	... 180 more
Caused by: java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
	at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
	... 183 more
Caused by: java.lang.NoClassDefFoundError: com/sun/image/codec/jpeg/JPEGCodec
	at com.sun.media.jai.codecimpl.JPEGImage.<init>(JPEGImageDecoder.java:106)
	at com.sun.media.jai.codecimpl.JPEGImageDecoder.decodeAsRenderedImage(JPEGImageDecoder.java:46)
	at com.sun.media.jai.opimage.CodecRIFUtil.create(CodecRIFUtil.java:88)
	at com.sun.media.jai.opimage.JPEGRIF.create(JPEGRIF.java:43)
	... 189 more
Caused by: java.lang.ClassNotFoundException: com.sun.image.codec.jpeg.JPEGCodec
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
	... 193 more

I am using “Aspose.Words 20.1” and my Java application runs with “openjdk 11.0.4-redhat 2019-07-16 LTS” on a “Windows 10 64-bit” workstation.

What I actions should I perform in order to overcome this issue?

@aspyr

Aspose.Words for Java depends upon the Java Advanced Imaging (JAI) package from Oracle in order to process some image formats such as TIFF. Please read the following article about installing JAI package.

Additional Dependencies

Please make sure that you have correctly installed the JAI. You can also add the JAI Jar files into your Java project. Please restate the system and test the scenario again.

If you still face problem, please ZIP and attach your document and code example here for testing. We will investigate the issue and provide you more information on it.

Dear Tahir,

thanks for your immediate response. I attach the simplest scenario that causes the problem as a JUnit test. test-case.zip (407.9 KB)

Regarding the installation of JAI I tried installing it on both windows and ubuntu os. On both of them I had some differences in comparison to what is described in the link you attached. More specifically:

  • Windows 10 - 64bit
    I tried installing the .exe files for JDK but I was getting an error message informing me that I have not a JDK installed, although I have JDK 11 installed. I only managed to install the .exe file for JRE pointing to the JDK location. Then I run again the application providing in the classpath the required jars but I get the same error message (check above Aspose.Words with Java throws InvocationTargetException due to limitation of JAI with Java 11)

  • Ubuntu 18.04 - 64 bit
    I moved the *.so files in lib(instead of lib amd64) folder since all other *.so fileds was located there. Also I removed lib/ext folder since java failed to start with the following message:
    <JAVA_HOME>/lib/ext exists, extensions mechanism no longer supported; Use -classpath instead
    Note, that I provided the jars located in lib/ext exists in the classpath. After running I get the same error( ckeck above Aspose.Words with Java throws InvocationTargetException due to limitation of JAI with Java 11)

Regards,
Antonis

@aspyr

You are facing this issue because JAI is not properly installed on your system. You can add JAI jars into your project as shown in attached screenshot to avoid this exception.
Jai jars.png (31.0 KB)

As I mentioned above, I added these jars in my project. However, I noticed that you ran the test case with JDK 1.8. This is the only that differs; I run the test case with JDK 11. From the stacktrace it seems that some com.sun… packages are missing from JDK11.

Note, that I tried to run the test case with JDK 1.8 and it worked as expected.

Regards,
Antonis

@aspyr

We will investigate this issue and will get back to you soon.

@aspyr

We have tested the scenario and have managed to reproduce the same issue at our side. For the sake of correction, we have logged this problem in our issue tracking system as WORDSJAVA-2318. You will be notified via this forum thread once this issue is resolved.

We apologize for your inconvenience.

@aspyr

It is to inform you that the issue which you are facing is actually not a bug in Aspose.Words. Please check the following detail about this issue.

The problem is JAI itself. It is a pretty outdated library and doesn’t keep up with the changes in new JDKs.

E.g. a quote from the Eclipse ImageN project JAI Migration - Eclipse ImageN

java.lang.NoClassDefFoundError: com/sun/image/codec/jpeg/ImageFormatException Oracle JDK 8 includes the internal com.sun.image.codec.jpeg packages used by imagen-codec JPEG read/write support listed above. These packages are not available in OpenJDK 8 or Java 11.

The best option is not to include the JAI in the classpath in the case of JDK 11 if possible. Also, you should consider ImageMagick as an alternative approach.

You can check if Aspose.Words can work with JAI/ImageMagic by using the following code.

 ExternalImageLibTest.checkLibraries();