我正在使用ImageIO,我正在尝试将代码打包到一个JAR中,但是,我发现(经过一些调试) PSD插件不在打包的JAR中。
我发现是因为这个答案中的代码:Add/remove ImageReader from jar to ImageIO-registry
在我的pom.xml中,我有以下ImageIO依赖项:
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-bmp</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-psd</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-core</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-metadata</artifactId>
<version>3.4</version>
</dependency>我使用的maven命令是:
clean compile assembly:single请注意我用来调试的代码:
ImageIO.scanForPlugins()
IIORegistry.getDefaultInstance().registerApplicationClasspathSpis()
val ir = ImageIO.getImageReadersByFormatName("PSD")
while (ir.hasNext())
{
val r = ir.next() as ImageReader
println(r)
}在IDE打印中:
com.twelvemonkeys.imageio.plugins.psd.PSDImageReader@1963006a当从命令行运行jar时,它不会打印任何东西,这使我相信PSD插件不是在JAR内部工作,而是如何工作?
发布于 2018-12-29 14:49:56
问题是,目标assembly:single将您自己项目中的“所有东西”合并到一个JAR中,但是跳过了那里存在的文件。
ImageIO依赖于Java的SPI/服务加载器机制,因此插件将通过META-INF\services\javax.imageio.spi.ImageReaderSpi加载。但是,当使用这样一个文件拥有多个JAR并使用assembly:single时,其中一个文件将“胜利”,而来自其他JAR的文件将被跳过。在您的项目中,imageio-bmp和imageio-psd都有这样的文件,第一个文件在最终的JAR中“获胜”。(看起来IDE以另一个顺序加载这些文件,正确的版本"wins",但这只是猜测)。
解决方案: Maven应该将所有META-INF\services\javax.imageio.spi.ImageReaderSpi文件合并到结果JAR中的一个文件中。为此,Maven需要更多的配置信息。
descriptor.xml添加到项目的根目录中,如下所示:<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<!-- copied from jar-with-dependencies (http://maven.apache.org/plugins/maven-assembly-plugin/descriptor-refs.html#jar-with-dependencies) -->
<id>jar-with-deps-merge-services</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<containerDescriptorHandlers>
<containerDescriptorHandler>
<handlerName>metaInf-services</handlerName>
</containerDescriptorHandler>
</containerDescriptorHandlers>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
</assembly>重要的部分是metaInf-services设置,它将文件合并到META-INF\services中。
descriptor.xml中添加对pom.xml的引用[...]
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<archive>
<manifest>
<mainClass>your.main.MainClass</mainClass>
</manifest>
</archive>
<descriptors>
<descriptor>descriptor.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>重要说明:
jar-with-dependencies,则应该将其删除,因为描述符文件包括该设置。即使我在一个示例项目上尝试了这一点,这个解决方案可能并不完美,您可能会根据您的需要对其进行调整,但我希望这是一个合适的起点。
https://stackoverflow.com/questions/53969942
复制相似问题