使用ImageIO
时,我得到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!.
我尝试this来解决我的问题,但它没有帮助。我MANIFEST.MF
中的jai_imageio.jar
包含所有必填信息:
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
重要 - 仅当我将程序作为导出的runnable jar文件运行而没有Eclipse时才会出现此错误。当我使用Eclipse运行时,一切正常。
答案 0 :(得分:0)
我知道它已经很老了,因此在SO上被问了很多遍,但是我遇到了同样的问题,标准解决方案也不适合我,所以我选择了这个解决方案来分享我的解决方案。我的清单中有所有属性(包括Specification-Vendor
,在OP的代码段中缺少),但是AWS EMR集群上的Hadoop RunJar类似乎将jar打包,因此清单被忽略了(我并没有真正对此进行更深入的调查)。
我最终得到了使用反射的解决方案:
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);
}
并为所有PackageUtil
类调用了此方法-就我而言:
com.sun.media.imageioimpl.common.PackageUtil.class,
io.scif.media.imageioimpl.common.PackageUtil.class,
com.github.jaiimageio.impl.common.PackageUtil.class
使用vendor
,version
和specType
的确切值并不重要,只要它们不是null
。