Issue
I'm getting this problem:
I have a project with spring-boot. It works perfectly on eclipse, but I need to generate a jar with dependencies, so I add the maven-assembly-plugin configuration to the pom.
Some spring dependencies has in the META-INF a file called spring.schemas, and I need to merge all spring.schemas into one (spring-context, spring-beans, etc)
I tried this solution using maven-shade-pluggin and AppendingTransformer, and it merges all spring.schemas perfectly... But it has an issue, when I execute the jar, it fails with:
java.lang.IllegalStateException: Unable to open nested entry 'lib/spring-boot-starter-batch-1.2.4.RELEASE.jar'.
It has been compressed and nested jar files must be stored without compression.
Please check the mechanism used to create your executable jar file
So, shade plugin compress the jar, and spring-boot doesn't like it, and there's no way to turn off the compression in shade. I manually copy the shade spring.schemas generated by shade and I put it in the maven-assembly-pluggin generated and uncompressed jar with dependencies. It works.
Then I tried to include the generated spring.schemas into my resources folder, but it's allways overrided by the spring.schemas from spring-context.
I also tried this other solution to exclude spring.schemas from dependency jar using a descriptor XML in assembly, but it doesn't work:
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>distribution</id>
<formats>
<format>jar</format>
</formats>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<includes>
<include>org.springframework:spring-context</include>
</includes>
<unpack>true</unpack>
<unpackOptions>
<excludes>
<exclude>**/spring.schemas</exclude>
</excludes>
</unpackOptions>
</dependencySet>
<dependencySet>
<outputDirectory>/</outputDirectory>
<excludes>
<exclude>org.springframework:spring-context</exclude>
</excludes>
<unpack>true</unpack>
</dependencySet>
</dependencySets>
</assembly>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>org.springframework.batch.core.launch.support.CommandLineJobRunner</mainClass>
</manifest>
<compress>false</compress>
</archive>
<descriptors>
<descriptor>src/main/assembly/distribution.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
This are my dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
</dependency>
<!-- MySql 5.5 Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
</dependencies>
Any ideas? Thanks in advance
Solution
Instead of using maven-assembly-plugin and maven-shade-pluggin, I would try to use Spring Boot's own spring-boot-maven-plugin that can be used to create an executable ‘fat’ JAR. See this reference documentation page, section "73.2 Create an executable JAR with Maven".
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
Or, if you don't use the spring-boot-starter-parent POM:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.2.5.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Answered By - Alin Pandichi
Answer Checked By - Robin (JavaFixing Admin)