【问题标题】:Maven 2 assembly plugin clobbers some META-INF filesMaven 2 程序集插件破坏了一些 META-INF 文件
【发布时间】:2010-11-01 13:15:14
【问题描述】:

我正在使用 Maven 2 程序集插件来构建一个 jar-with-dependencies 并制作一个可执行的 JAR 文件。我的程序集包括 Spring 和 CXF 库。

CXF 包括 META-INF 文件 spring.schemas 和 spring.handlers 的副本,它们最终会破坏 spring-2.5.4 jar 中的类似文件。

我可以手动更新 jar-with-dependencies 中的这两个文件。

我正在寻找的是 Maven POM 中的某种方式来指导程序集插件获取这两个文件的正确版本。

程序集插件文档讲了文件过滤,但似乎没有配置或参数,没有去创建自定义程序集描述符的麻烦。

在这种情况下,我唯一的希望是制作自定义程序集描述符吗?

【问题讨论】:

  • “spring.tooling”文件也会发生同样的事情,但从它们的名字来看,我猜它们不会在运行时使用。

标签: java spring maven-2


【解决方案1】:

我已经解决了,这里是详细信息:

首先,如果您使用内置程序集描述符 jar-with-dependencies,则无法指定文件包含或排除。

程序集插件文档给出了示例jar-with-dependencies descriptor here

我将该描述符复制并粘贴到我的项目目录中名为 exec-jar.xml 的文件中。然后在 pom 中,我更改了程序集插件以引用该描述符。摘录如下:

<build>
  <plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.2-beta-3</version>
        <configuration>
            <descriptors>
                <descriptor>exec-jar.xml</descriptor>
            </descriptors>
            <archive>
                <manifest>
                    <mainClass>com.package.MyMainClass</mainClass>
                </manifest>
            </archive>
        </configuration>
        <executions>
            <execution>
                <id>make-assembly</id>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
  </plugins>
</build>

那位描述符将程序集绑定到生命周期的包阶段,并引用 exec-jar.xml 描述符。执行该包确认 jar 的构建与使用预定义描述符一样。

那么接下来就是修改 exec-jar.xml 以排除与 Spring 文件冲突的 CXF 文件。这是我的程序集描述符,它实现了这一点:

<assembly>
  <id>jar-with-dependencies</id>
  <formats>
    <format>jar</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <dependencySets>
    <dependencySet>
      <unpack>true</unpack>
      <unpackOptions>
        <excludes>
            <exclude>cxf*/META-INF/spring.handlers</exclude>
            <exclude>cxf*/META-INF/spring.schemas</exclude>
        </excludes>
      </unpackOptions>
      <scope>runtime</scope>
    </dependencySet>
  </dependencySets>
  <fileSets>
    <fileSet>
      <directory>${project.build.outputDirectory}</directory>
    </fileSet>
  </fileSets>
</assembly>

现在问题来了。如果您使用当前发布的程序集插件 2.1 版执行此操作,它将在标记上失败,并显示为“意外”。该标签在插件的未发布版本 2.2 中受支持。请注意,在我上面的 pom 文件摘录中,我指定了 maven-assembly-plugin 版本 2.2-beta-3,这是撰写本文时的最新版本。

这成功构建了一个可执行 jar,Spring 拥有初始化我的应用所需的所有处理程序和架构。

【讨论】:

    【解决方案2】:

    我建议改用 maven-shade-plugin。如果您查看 cxf-bundle (https://github.com/apache/cxf/blob/master/pom.xml) 的 pom,您可以了解如何使用阴影转换器合并 spring.schemas 和其他必要文件。

    【讨论】:

      【解决方案3】:

      您还可以通过从您想要的 spring 发行版中获取 spring.schemas 和 spring.handlers 文件并将它们放在项目的 src/main/resources/META-INF 目录中来解决此问题。由于这些是最后打包的,因此您将获得所需的版本。我找到了这个想法here

      【讨论】:

        【解决方案4】:

        由于某种原因,Mojo 和其他人建议的解决方案仍然对我不起作用。我创建了我的自定义spring.handlersspring.schemas 文件并将它们放在src/main/resources/META-INF 下。但是,当使用 unpackOptions 时,我的文件也不包括在内。当我不使用 unpackOptions 时,我的文件不是 jar 中的文件。

        我最终做的是直接引用文件。这最终将我的文件放入 JAR。

        <assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
            <!-- TODO: a jarjar format would be better -->
            <id>jar-with-dependencies</id>
            <formats>
                <format>jar</format>
            </formats>
            <includeBaseDirectory>false</includeBaseDirectory>
            <dependencySets>
                <dependencySet>
                    <outputDirectory>/</outputDirectory>
                    <unpack>true</unpack>
                    <unpackOptions>
                        <excludes>
                            <exclude>META-INF/spring.handlers</exclude>
                            <exclude>META-INF/spring.schemas</exclude>
                        </excludes>
                    </unpackOptions>
                    <scope>runtime</scope>
                </dependencySet>
            </dependencySets>
            <files>
                <file>
                    <source>${project.basedir}/src/main/resources/META-INF/spring.handlers</source>
                    <outputDirectory>META-INF</outputDirectory>
                </file>
                <file>
                    <source>${project.basedir}/src/main/resources/META-INF/spring.schemas</source>
                    <outputDirectory>META-INF</outputDirectory>
                </file>
            </files>
        </assembly>
        

        【讨论】:

        • 确实这个解决方案更好,更通用。当早期的排除出于某种原因对我不起作用时,我不得不自己依靠它。
        • 我必须添加 true 才能将类包含在同一个项目中。
        【解决方案5】:

        我尝试了阴影插件方法,效果非常好。这是您需要放入 POM 的所有内容(无需汇编插件)。

              <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-shade-plugin</artifactId>
                    <version>1.4</version>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>shade</goal>
                            </goals>
                            <configuration>
                                <transformers>
                                    <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                        <mainClass>org.example.Runner</mainClass>
                                    </transformer>
                                    <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                        <resource>META-INF/spring.handlers</resource>
                                    </transformer>
                                </transformers>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
        

        【讨论】:

          【解决方案6】:

          如果您从 Mojo 的回答中收到配置错误:

          错误:发生 JNI 错误,请检查您的安装并重试 线程“main”中的异常 java.lang.SecurityException:Manifest 主要属性的签名文件摘要无效

          对我来说,以下工作:http://zhentao-li.blogspot.de/2012/06/maven-shade-plugin-invalid-signature.html

            <filters>
              <filter>
                <artifact>*:*</artifact>
                <excludes>
                  <exclude>META-INF/*.SF</exclude>
                  <exclude>META-INF/*.DSA</exclude>
                  <exclude>META-INF/*.RSA</exclude>
                </excludes>
              </filter>
            </filters>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-12-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-06-22
            • 2010-11-20
            • 2016-12-14
            • 1970-01-01
            相关资源
            最近更新 更多