JAI 供应商名称 == null
因此,我完成了旋转 TIFF 图像的应用程序的编码,这需要 JAI 来操作 TIFF。
在 Eclipse 下工作时它工作得很好,但是每当我为库构建一个胖罐子,然后创建一个实现该罐子时(根据 http://fjep.sourceforge.net/fjeptutorial.html),当我执行 java -jar Push.jar \path\to\dir 时,它会一直运行,直到到达正在压缩的部分为止保存:
TIFFImageWriterSpi tiffspi = new TIFFImageWriterSpi();
ImageWriter writer = tiffspi.createWriterInstance();
//Iterator<ImageWriter> 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.
So I finished coding my application to rotate TIFF images which required JAI to manipulate the TIFFs.
It works fine when working under Eclipse, but whenever I build a fat jar for the library and then create one implementing that (per http://fjep.sourceforge.net/fjeptutorial.html), when I do the java -jar Push.jar \path\to\dir, it runs up until it hits the part where it is compressing and saving:
TIFFImageWriterSpi tiffspi = new TIFFImageWriterSpi();
ImageWriter writer = tiffspi.createWriterInstance();
//Iterator<ImageWriter> 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.");
It blows up on the first line of that section with the message:
Exception in thread "main" java.lang.IllegalArgumentException: vendorName == null!
....rest of stack trace.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
由于我花了相当多的时间来调试这个问题,所以我想我会在这里分享我的解决方案,尽管这个问题已经存在很久了。 Srikanth 的第二个链接特别有帮助。
错误原因
JAI 需要为其一些深层内部提供供应商名称,特别是 javax.imageio.spi.IIOServiceProvider,许多(全部?)图像读取器将其用于低级 IO。字符串是什么并不挑剔,但它不能为空。
ImageReaderSpi 类不是硬编码供应商名称,而是从 sun.media.imageioimpl.common.PackageUtil.getVendor() 获取供应商名称。这反过来从 jar 的 MANIFEST.MF 中读取它。通常,您会链接到标准 jai-imageio 软件包,以便读取 Sun 的供应商信息。然而,由于您正在制作一个 fat jar 文件,因此您将 Sun 的 MANIFEST.MF 替换为您自己的,但缺少所需的信息。
解决方案
在 MANIFEST.MF 文件中包含以下行:
每个属性的值可以是任何值(我使用了我的特定应用程序/版本/公司),只要定义了所有六个即可。
Maven
如果您使用 maven 的程序集插件来创建 fat jar,maven 可以自动包含正确的版本号等。使用以下
部分更新您的pom.xml
:Since I spent a considerable amount of time debugging this problem, I thought I would share my solution here, despite the age of the question. Srikanth's second link was particularly helpful.
Reason for the error
JAI requires a vendor name for some of its deep internals, particularly the javax.imageio.spi.IIOServiceProvider which gets used by many (all?) of the image readers for their low-level IO. It's not picky what the string is, but it can't be null.
Rather than hard-code the vendor name, the ImageReaderSpi class gets the vendor name from sun.media.imageioimpl.common.PackageUtil.getVendor(). This in turn reads it from the jar's MANIFEST.MF. Normally you link against the standard jai-imageio packagage, so Sun's vendor info gets read. However, since you're making a fat jar file, you replaced Sun's MANIFEST.MF with your own which lacks the required information.
Solution
Include the following lines in your MANIFEST.MF file:
The values for each property can be anything (I used my specific application/version/company), as long as all six are defined.
Maven
If you were using maven's assembly plugin to create your fat jar, maven can automatically include the correct version numbers and such. Update your
pom.xml
with the following<archive>
section:我必须使用这个 ImageIO jar。它就像一个魅力。在此处找到它。
I had to use this ImageIO jar. It worked like a charm. Found it here.
Quantum7 接受的答案解释了问题的根源,并在 Maven 部分中提供了使用 Maven Assembly 插件生成包含依赖项的 JAR 时的解决方案。如果您改用 Maven Shade 插件来生成具有依赖项的 JAR,则配置会略有不同。您可以将如下内容添加到
pom.xml
中 Shade 插件的配置部分:The accepted answer by Quantum7 explains the source of the problem, and in the Maven section it provides a solution when using the Maven Assembly plugin to produce a JAR including dependencies. If you are instead using the Maven Shade plugin to produce the JAR with dependencies, the configuration is slightly different. You can add something like the following to the configuration section of the Shade plugin in your
pom.xml
:免责声明
我遇到的问题略有不同,我在尝试运行编译的 jar 文件时收到“ClassNotFound”错误。我在研究时偶然发现了这个问题,所以对于那些和我有同样经历的人来说,就在这里。
ClassNotFound 错误的可能解决方案
对于那些稍后可能会发现此问题的人,如果其他方法似乎不起作用,您可以尝试使用 Apache Shader Maven 插件。 这里是一些关于它的更多信息。
我的经验不够,无法告诉您它如何,但是 Apache Shader 将项目中所有使用的依赖项打包到最终的 jar 文件中,以便所有依赖项都包含在构建后的 META-INF 文件夹。这会增加 jar 文件的大小(取决于您在项目中使用的库的数量),但似乎也修复了 jar 无法从所使用的外部库中找到类的问题。
要使用 Shader 插件,请将以下内容添加到 POM 中。我将其包含在依赖项标记之后和属性标记之前。
注意:确保更改包和类名称以反映项目的包和类名称。
其他有用的链接:类似的堆栈溢出问题
DISCLAIMER
The issue that I was having was slightly different, I was getting the "ClassNotFound" error while trying to run a compiled jar file. I happened upon this SO question while researching, so for others who followed the same trail that I did, here you go.
Possible Solution to ClassNotFound Error
To those who may find this question later on, if nothing else seems to work, You could try using the Apache Shader plugin for Maven. Here is some more information on it.
I'm not experienced enough to be able to tell you how it does it, but Apache Shader packages all the used dependencies in your project into the final jar file, so that all the dependencies are included in the META-INF folder when it's built. This increases the size of the jar file (depending on how many libraries you used in your project), but also seems to fix the jar not being able to find classes from outside libraries that are used.
To use the Shader plugin, add the following to your POM. I included it after the dependencies tag and before the properties tag.
NOTE: Make sure you change the package and class name to reflect your project's package and class names.
Other useful links: Similar stack overflow question
(如果我有足够的声誉,就会对 Quantum7 的答案发表评论)
我遇到了同样的问题。 Quantum7 的回答挽救了局面!然而,在放入manifestEntriesSpecification-Vendor和Implementation-Vendor之后,我的fat jar的执行仍然失败,出现以下异常。注意是
不是
放入下面的manifestEntries 修复了它。
运行 fat jar 时,我确保下面代码中的三个值都不为空。
(Would have been a comment on Quantum7's answer if I had enough reputation)
I ran into the same problem. Quantum7's answer saved the day! After putting in manifestEntries Specification-Vendor and Implementation-Vendor, however, the execution of my fat jar still failed with the exception below. Note it is
not
Putting in manifestEntries below fixed it.
When running the fat jar, I made sure that none of the three values in the code below is null.
这些都可以帮助你解决问题。
如何使用源代码运行 jai-imageio
vendorName == null
These can help you to solve the problem.
How to run jai-imageio with source code
vendorName == null
在努力寻找许多解决方案后,我也遇到了同样的错误,发现了这个并为我工作。
需要在代码中手动给出 venderName,如下所示:
如果供应商名称值不为 NULL,则该值是什么并不重要。
我的代码在 Eclipse 中运行良好,但在导出的可运行 jar 中给出异常。
写完上面的代码并导出jar后终于成功了。
I was also getting the same error after struggling for many solution found this and worked for me.
Need to give venderName manually in code as:
It doesn't matter what will be the vendorName value is if it's not NULL.
My code was running fine in eclipse but giving exceptions in an exported runnable jar.
Finally worked when wrote the above code and exported the jar.
我遇到了同样的问题,根据这里之前的答案,我构建了一个适合我的 maven-shade-plugin 的配置。我将其放在这里作为其他人的模板:
I had the same issue and based on previous answers in here I constructed a configuration for the maven-shade-plugin that worked for me. I include it here as a template for others: