lunedì 16 novembre 2020

Java image rendering and Crystal report Error the definitive guide !

I've be working for a while into a Crystal report Java project.

The aim is to generate in background and email PDF files produced by Crystal report document, I built two projects on that one that generate over a http call the desired document and the second that runs every n minutes lookup the lines in a table and produce the related documents.

Everything works quite well in Eclipse but when you move in production on a linux machine there's come the rain.

The first error in the stack comes with these lines:

 javax.imageio.spi.ImageReaderSpi: Provider com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageReaderSpi could not be instantiated
        at java.util.ServiceLoader.fail(Unknown Source)
        at java.util.ServiceLoader.access$100(Unknown Source)
        at java.util.ServiceLoader$LazyIterator.nextService(Unknown Source)
        at java.util.ServiceLoader$LazyIterator.next(Unknown Source)
        at java.util.ServiceLoader$1.next(Unknown Source)
        at javax.imageio.spi.IIORegistry.registerApplicationClasspathSpis(Unknown Source)


So i'm started struggling to find if there's a missing library or not trying to repack the jar in different ways without success.

 After a day (or more) spent and a very big headache, I scrolled down the log... saying to myself in case there's some other interesting information....  and taac here's the trick, the root cause is java.lang.IllegalArgumentException: vendorName == null!

  Caused by: java.lang.IllegalArgumentException: vendorName == null!
 
       at javax.imageio.spi.IIOServiceProvider.<init>(Unknown Source)
        at javax.imageio.spi.ImageReaderWriterSpi.<init>(Unknown Source)
        at javax.imageio.spi.ImageReaderSpi.<init>(Unknown Source)
        at com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageReaderSpi.<init>(CLibJPEGImageReaderSpi.java:80)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
        at java.lang.reflect.Constructor.newInstance(Unknown Source)
        at java.lang.Class.newInstance(Unknown Source)
        ... 99 more

This type of error handling is one of the thing that makes me hate java but on the other hand, i still love it, not easy language to learn but very powerfull and clean!


So, googling a bit I found some useful tips: https://stackoverflow.com/questions/7051603/jai-vendorname-null

https://thierrywasyl.wordpress.com/2009/07/24/jai-how-to-solve-vendorname-null-exception/

The solution is to add these lines in a manifest.mf file after the jar is produced, put that in the META-INF directory

Implementation-Vendor: Sun Microsystems, Inc
Implementation-Title: Java Runtime Environment
Implementation-Version: 1.6.0