Serhii Tereshchenko
Serhii Tereshchenko

Reputation: 197

JAI vendorname == null (standard solution doesn't work)

While using ImageIO I get this java.util.ServiceConfigurationError:

javax.imageio.spi.ImageInputStreamSpi: Provider com.sun.media.imageioimpl.stream.ChannelImageInputStreamSpi could not be instantiated caused by: java.lang.IllegalArgumentException: vendorName == null!.

I tried this to solve my problem, but it didn't help. My MANIFEST.MF in jai_imageio.jar contains all required info:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.2
Created-By: 1.4.2_12-b03 (Sun Microsystems Inc.)
Specification-Title: Java Advanced Imaging Image I/O ToolsSun Microsystems, Inc.
Implementation-Title: com.sun.media.imageio
Implementation-Version: 1.1
Specification-Version: 1.1
Implementation-Vendor: Sun Microsystems, Inc.
Extension-Name: com.sun.media.imageio
Sealed: true

Important - this error occures only when I run my program as exported runnable jar file without Eclipse. When I run with Eclipse everything works fine.

Upvotes: 3

Views: 3210

Answers (1)

Patter
Patter

Reputation: 1299

I know it's old and has been asked many times on SO, but I had the same problem and the standard solution didn't work for me either, so I picked this one to share my solution. I have all the attributes in my manifest (including Specification-Vendor, which is missing in the OP's snippet) but the Hadoop RunJar class on AWS EMR clusters seems to unpack the jar and thus the manifest is ignored (I didn't really investigate that in more depth). I ended up with a solution using reflection:

public static void tweakPackageUtil (Class<?> packageUtilClass, String vendor, String version, String specTitle) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException
{
    Field vendorField = packageUtilClass.getDeclaredField("vendor");
    vendorField.setAccessible(true);
    vendorField.set(null, vendor);

    Field versionField = packageUtilClass.getDeclaredField("version");
    versionField.setAccessible(true);
    versionField.set(null, version);

    Field specTitleField = packageUtilClass.getDeclaredField("specTitle");
    specTitleField.setAccessible(true);
    specTitleField.set(null, specTitle);
}

and called this method for all PackageUtil classes - in my case:

com.sun.media.imageioimpl.common.PackageUtil.class,
io.scif.media.imageioimpl.common.PackageUtil.class,                                                                            
com.github.jaiimageio.impl.common.PackageUtil.class

It doesn't really matter what exact values for vendor, version and specType are used as long as they are not null.

Upvotes: 1

Related Questions