Maven构建jar:合并来自依赖项的重复资源

时间:2015-07-09 07:52:54

标签: maven spring-boot maven-assembly-plugin maven-bundle-plugin

我遇到了这个问题:

我有一个带有spring-boot的项目。它在eclipse上运行得很好,但我需要生成一个带有依赖项的jar,所以我将maven-assembly-plugin配置添加到pom中。

一些Spring依赖项在META-INF中有一个名为spring.schemas的文件,我需要将所有spring.schemas合并为一个(spring-context,spring-beans等)

我使用maven-shade-pluggin和AppendingTransformer尝试了this solution,它完全合并了所有spring.schemas ......但它有一个问题,当我执行jar时,它失败了:

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

因此,阴影插件压缩罐子,弹簧靴不喜欢它,并且没有办法在阴影中关闭压缩。我手动复制由shade生成的shade spring.schemas,并将它放在maven-assembly-pluggin生成和未压缩的jar中,具有依赖关系。它有效。

然后我尝试将生成的spring.schemas包含到我的资源文件夹中,但它总是被spring-context中的spring.schemas覆盖。

我还尝试this other solution在程序集中使用描述符XML从依赖jar中排除spring.schemas,但它不起作用:

<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>

这是我的依赖:

<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>

有什么想法吗?提前致谢

2 个答案:

答案 0 :(得分:0)

我会尝试使用Spring Boot自己的spring-boot-maven-plugin,而不是使用maven-assembly-plugin和maven-shade-pluggin,可以用来创建一个可执行的'fat'JAR。请参阅this reference documentation page,“73.2使用Maven创建可执行JAR”部分。

<build>
<plugins>
    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
</plugins>

或者,如果您不使用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>

答案 1 :(得分:0)

您可以使用 maven-assembly-plugin

将插件添加到您的 pom.xml

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <version>3.1.1</version>
  <executions>
    <execution>
      <id>make-assembly</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <descriptors>
      <descriptor>fat-jar.xml</descriptor>
    </descriptors>
  </configuration>
</plugin>

在您的 fat-jar.xml 旁边添加一个 pom.xml 描述符:

<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
  <id>fat</id>
  <formats>
    <format>jar</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <dependencySets>
    <dependencySet>
      <outputDirectory>/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <unpack>true</unpack>
      <scope>runtime</scope>
    </dependencySet>
  </dependencySets>
  <containerDescriptorHandlers>
    <containerDescriptorHandler>
      <handlerName>metaInf-spring</handlerName>
    </containerDescriptorHandler>
  </containerDescriptorHandlers>
</assembly>

注意 metaInf-spring 处理程序。它将合并名称以 spring 字开头的任何 META-INF 重复文件。

参考文档:https://maven.apache.org/plugins/maven-assembly-plugin/examples/single/using-container-descriptor-handlers.html