Проблема в том, что цель assembly:single
объединяет «все» из вашего собственного проекта и всех JAR-файлов, на которые есть ссылки, в один JAR, но пропускает файлы, которые там еще существуют.
ImageIO использует механизм загрузки SPI / serviceJava и, следовательно, плагины будут загружены через META-INF\services\javax.imageio.spi.ImageReaderSpi
.Однако при наличии более одного JAR с таким файлом и использовании assembly:single
один из этих файлов «выигрывает», а другие из других JAR пропускаются.В вашем проекте оба файла imageio-bmp
и imageio-psd
имеют такой файл, и первый из них "выигрывает" в полученном JAR-файле.(Похоже, IDE загружает эти файлы в другом порядке, и правильная версия «выигрывает», но это всего лишь предположение.)
Решение: 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>
Важные примечания:
- Maven-версия сборки-плагина должна быть 2.2.1, потому что текущая версия 3.x не работает.Тем не менее, вы можете попробовать более новые версии 2.2.x или 2.x, если это действительно необходимо.Я только пробовал 2.2.1, и он работает.
- Блок основного класса должен быть изменен в соответствии с именем вашего основного класса, если вам это нужно.
- Файл дескриптора может быть помещен вдругой каталог в вашем проекте, но затем необходимо изменить ссылку в pom (это относительно корня вашего проекта maven).
- Если у вас есть
jar-with-dependencies
в вашей конфигурации сборки, это должно бытьудален, потому что файл дескриптора включает эту настройку.
Даже при том, что я попробовал это на примере проекта, это решение может быть не идеальным, и вы можете адаптировать его в соответствии со своими потребностями, но я надеюсь, что этоподходящая точка для начала.