JAI vendorname == null

所以我完成了我的应用程序编码以旋转TIFF图像,这需要JAI来操纵TIFF。

它在Eclipse下工作时工作正常,但每当我为库构建一个胖jar然后创建一个实现它(根据http://fjep.sourceforge.net/fjeptutorial.html ),当我执行java -jar Push时。 jar \ path \ to \ _dir,它会一直运行直到它到达压缩和保存的部分:

TIFFImageWriterSpi tiffspi = new TIFFImageWriterSpi(); ImageWriter writer = tiffspi.createWriterInstance(); //Iterator iter = ImageIO.getImageWritersByFormatName("TIFF"); //ImageWriter writer = iter.next(); ImageWriteParam param2 = writer.getDefaultWriteParam(); param2.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); param2.setCompressionType("LZW"); param2.setCompressionQuality(0.0f); File fOutputFile = workArea[i]; ImageOutputStream ios = ImageIO.createImageOutputStream(fOutputFile); writer.setOutput(ios); if (frontPage == 1) { writer.write(null, new IIOImage(pg1, null, null), param2); writer.writeInsert(-1, new IIOImage(pg2, null, null), param2); } else if (frontPage == 2) { writer.write(null, new IIOImage(pg2, null, null), param2); writer.writeInsert(-1, new IIOImage(pg1, null, null), param2); } remaining = remaining - 1; if (remaining > 0) System.out.println(remaining + " remaining."); else System.out.println("Done."); 

它在该部分的第一行爆炸,并带有以下消息:

  Exception in thread "main" java.lang.IllegalArgumentException: vendorName == null! ....rest of stack trace. 

由于我花了相当多的时间来调试这个问题,我想我会在这里分享我的解决方案,尽管问题的年代。 Srikanth的第二个链接特别有用。

错误原因

JAI需要一些深层内部的供应商名称,特别是javax.imageio.spi.IIOServiceProvider,它被许多(所有?)图像阅读器用于它们的低级IO。 字符串是什么并不挑剔,但它不能为空。

ImageReaderSpi类不是硬编码供应商名称,而是从sun.media.imageioimpl.common.PackageUtil.getVendor()获取供应商名称。 这反过来从jar的MANIFEST.MF读取它 。 通常,您会链接到标准的jai-imageio包,因此Sun的供应商信息会被读取。 但是,由于您正在创建一个胖jar文件,因此您将Sun的MANIFEST.MF替换为您自己的缺少所需信息的MANIFEST.MF。

在MANIFEST.MF文件中包含以下行:

规范标题:Java高级成像图像I / O工具
规范 - 版本:1.1
规范 - 供应商:Sun Microsystems,Inc。
实现 - 标题:com.sun.media.imageio
实施 - 版本:1.1
实施 - 供应商:Sun Microsystems,Inc。 

每个属性的值可以是任何值(我使用我的特定应用程序/版本/公司),只要定义了所有六个属性。

Maven的

如果您使用maven的程序集插件来创建胖jar,maven可以自动包含正确的版本号等。 使用以下部分更新pom.xml

  org.apache.maven.plugins maven-assembly-plugin   jar-with-dependencies    true true   MyCompany MyCompany      create-my-bundle package  single     

我不得不使用这个ImageIO jar 。 它就像一个魅力。 在这里找到它。

Quantum7接受的答案解释了问题的根源,在Maven部分,它提供了一个解决方案,当使用Maven Assembly插件生成包含依赖关系的JAR时。 如果您使用Maven Shade插件来生成具有依赖项的JAR,则配置略有不同。 您可以在pom.xml中的Shade插件的配置部分添加以下内容:

     com.conveyal.r5.R5Main Java Advanced Imaging Image I/O Tools 1.1 Sun Microsystems, Inc. com.sun.media.imageio 1.1 Sun Microsystems, Inc. com.sun.media.imageio     

这些可以帮助您解决问题。

如何使用源代码运行jai-imageio

vendorName == null

免责声明

我遇到的问题略有不同,我在尝试运行编译的jar文件时遇到“ClassNotFound”错误。 我在研究时碰巧遇到了这个问题,所以对于那些跟我走过同样道路的人来说,你走了。

ClassNotFound错误的可能解决方案

对于那些可能在以后找到这个问题的人来说,如果没有其他似乎可行的话,你可以尝试使用Maven的Apache Shader插件。 这里有一些关于它的更多信息。

我没有足够的经验告诉你它是如何做到的,但Apache Shader将项目中所有使用的依赖项打包到最终的jar文件中,以便所有依赖项都包含在META-INF文件夹中。 这会增加jar文件的大小(取决于您在项目中使用的库数量),但似乎也修复了jar无法从使用的外部库中查找类的问题。

要使用Shader插件,请将以下内容添加到POM中。 我将它包含在依赖项标记之后和属性标记之前。

    org.apache.maven.plugins maven-shade-plugin 2.4.3   package  shade     *:*  META-INF/*.SF META-INF/*.DSA META-INF/*.RSA       com.package.name.className 1          

注意 :确保更改包和类名以反映项目的包和类名。

其他有用的链接: 类似的堆栈溢出问题

(如果我有足够的声誉,本来可以评论Quantum7的答案)

我遇到了同样的问题。 Quantum7的答案节省了一天! 然而,在放入manifestEntries Specification-Vendor和Implementation-Vendor之后,我的fat jar的执行仍然失败,下面有例外。 注意它是

version == null!

vendorName == null!

 java.util.ServiceConfigurationError: 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) at javax.imageio.spi.IIORegistry.(Unknown Source) at javax.imageio.spi.IIORegistry.getDefaultInstance(Unknown Source) at javax.imageio.ImageIO.(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: java.lang.IllegalArgumentException: version == null! at javax.imageio.spi.IIOServiceProvider.(Unknown Source) at javax.imageio.spi.ImageReaderWriterSpi.(Unknown Source) at javax.imageio.spi.ImageReaderSpi.(Unknown Source) at com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageReaderSpi.(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) ... 14 more 

放入下面的manifestEntries修复它。

  Java Advanced Imaging Image I/O Tools 1.1 Sun Microsystems, Inc. com.sun.media.imageio 1.1 Sun Microsystems, Inc.  

运行fat jar时,我确保下面代码中的三个值都不为null。

 import com.sun.media.imageioimpl.common.PackageUtil; public class ManifestCheck { public static void main(String[] args) { System.out.println(PackageUtil.getVendor()); System.out.println(PackageUtil.getVersion()); System.out.println(PackageUtil.getSpecificationTitle()); } }