简体   繁体   English

Maven 2 程序集插件破坏了一些 META-INF 文件

[英]Maven 2 assembly plugin clobbers some META-INF files

I'm using the Maven 2 assembly plug-in to build a jar-with-dependencies and make an executable JAR file.我正在使用 Maven 2 程序集插件来构建一个 jar-with-dependencies 并制作一个可执行的 JAR 文件。 My assembly includes Spring, and the CXF library.我的程序集包括 Spring 和 CXF 库。

CXF includes copies of META-INF files spring.schemas and spring.handlers which end up clobbering the similar files from the spring-2.5.4 jar. CXF 包括 META-INF 文件 spring.schemas 和 spring.handlers 的副本,它们最终破坏了 spring-2.5.4 jar 中的类似文件。

By hand, I can update those two files within the jar-with-dependencies.我可以手动更新 jar-with-dependencies 中的这两个文件。

What I'm looking for is some way in the Maven POM to direct the assembly plug-in to get the correct version of those two files.我正在寻找的是 Maven POM 中的某种方式来指导程序集插件以获取这两个文件的正确版本。

The assembly plug-in documentation talks about file filtering, but doesn't seem to have configuration for or parameters, without going to the trouble of creating a custom assembly descriptor.程序集插件文档谈到了文件过滤,但似乎没有配置或参数,不用去创建自定义程序集描述符的麻烦。

Is making a custom assembly descriptor my only hope in this instance?在这种情况下,制作自定义程序集描述符是我唯一的希望吗?

For some reason the solution that Mojo and the others are suggesting still doesn't work for me.出于某种原因,Mojo 和其他人建议的解决方案仍然对我不起作用。 I've created my custom spring.handlers and spring.schemas files and put them under src/main/resources/META-INF .我已经创建了我的自定义spring.handlersspring.schemas文件,并将它们放在src/main/resources/META-INF However, when using the unpackOptions my files are not included as well.但是,当使用unpackOptions我的文件也不包含在内。 When I don't use the unpackOptions my files aren't the ones in the jar.当我不使用unpackOptions我的文件不是 jar 中的文件。

What I ended up doing is to reference the files directly.我最终做的是直接引用文件。 This finally put my files into the 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>

I tried the shade plugin approach and it worked very nicely.我尝试了阴影插件方法,效果很好。 Here is all you need to put in your POM (no assembly plugin needed).这是您需要放入 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>

I would suggest using the maven-shade-plugin instead.我建议改用 maven-shade-plugin。 If you look at the pom for the cxf-bundle ( https://github.com/apache/cxf/blob/master/pom.xml ) you can see how you can use the shade transformers to merge the spring.schemas and other necessary files.如果您查看 cxf-bundle ( https://github.com/apache/cxf/blob/master/pom.xml ) 的 pom,您会看到如何使用阴影变换器来合并 spring.schemas 和其他必要的文件。

I worked it out, and here are the details:我已经解决了,以下是详细信息:

First, there's no way to specify file includes or excludes if you use the built-in assembly descriptor jar-with-dependencies.首先,如果您使用内置程序集描述符 jar-with-dependencies,则无法指定文件包含或排除。

The assembly plug-in documentation gives the sample jar-with-dependencies descriptor here .组件插件文档在此处提供了示例jar-with-dependencies 描述符

I copied and pasted that descriptor to a file in my project directory called exec-jar.xml.我将该描述符复制并粘贴到我的项目目录中名为 exec-jar.xml 的文件中。 Then in the pom, I changed the assembly plug-in to reference that descriptor.然后在 pom 中,我更改了程序集插件以引用该描述符。 Here's the excerpt:这是摘录:

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

That bit of descriptor binds the assembly to the package phase of the life-cycle, and references the exec-jar.xml descriptor.该描述符位将程序集绑定到生命周期的包阶段,并引用 exec-jar.xml 描述符。 Doing that package confirmed that the jar was built just as it was with the predefined descriptor.执行该包确认 jar 的构建与预定义的描述符一样。

So then it becomes a matter of modifying exec-jar.xml to exclude the CXF files that conflict with the Spring files.那么接下来就是修改 exec-jar.xml 以排除与 Spring 文件冲突的 CXF 文件。 Here is my assembly descriptor that accomplished that:这是我完成的程序集描述符:

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

Now here's the rub.现在问题来了。 If you do this with the currently released assembly plug-in, version 2.1, it will fail on the tag as "unexpected."如果您使用当前发布的程序集插件 2.1 版执行此操作,它将失败标记为“意外”。 The tag is supported in unreleased version 2.2 of the plug-in.插件的未发布版本 2.2 支持该标签。 Note in my pom file excerpt above, I specify maven-assembly-plugin version 2.2-beta-3 which was the latest at the time of writing.请注意,在上面的 pom 文件摘录中,我指定了 maven-assembly-plugin 版本 2.2-beta-3,这是撰写本文时的最新版本。

This successfully built an executable jar, and Spring had all of the handlers and schemas it needed to initialize my app.这成功地构建了一个可执行 jar,并且 Spring 拥有初始化我的应用程序所需的所有处理程序和模式。

You can also work around the problem by getting the spring.schemas and spring.handlers files from the spring distro you want and put them in your projects src/main/resources/META-INF directory.您还可以通过从您想要的 spring 发行版获取 spring.schemas 和 spring.handlers 文件并将它们放在您的项目 src/main/resources/META-INF 目录中来解决这个问题。 Since those are packaged last, you'll get the version you want.由于这些是最后打包的,因此您将获得所需的版本。 I found the idea here我在这里找到了这个想法

If you get the error with the config from Mojo's answer:如果您从 Mojo 的回答中收到配置错误:

Error: A JNI error has occurred, please check your installation and try again Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes错误:发生 JNI 错误,请检查您的安装并重试线程“main”中的异常 java.lang.SecurityException:Manifest main 属性的签名文件摘要无效

For me the following worked: http://zhentao-li.blogspot.de/2012/06/maven-shade-plugin-invalid-signature.html对我来说,以下工作: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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM