如何合并Maven程序集中的资源文件?

时间:2009-10-22 13:31:05

标签: maven-2 assemblies build-automation

我正在使用Maven及其程序集插件来构建我的项目的分发包:

  • 一个项目在ZIP文件中组装一个基本的运行时(基于Felix)和相应的目录和包。
  • 第三方库分别收集在一个项目中,并转换为OSGi包,如果它们已经兼容OSGi,则只需复制它们
  • 我自己的项目也包含几个内置于OSGi包中的模块。

现在,我正在添加另一个解压缩ZIP的项目,将所有其他JAR放入正确的目录中,然后重新打包以进行分发。现在,我的bundle可能包含我要合并到的配置文件,而不是替换运行时程序集中名称相同的配置文件。我该怎么做?

文件是纯文本(属性文件),但稍后我可能会遇到与XML文件类似的情况。

5 个答案:

答案 0 :(得分:24)

对于那些偶然发现的人来说,对Juergen的答案进行了扩展 - 描述符中的containerDescriptorHandler可以采用四个值(v2.3),这些是metaInf-servicesfile-aggregator,{ {1}},plexus。它有点埋没在代码中(在包metaInf-spring中找到)但是可以聚合配置/属性文件。

这是一个聚合org.apache.maven.plugin.assembly.filter和{。}的示例描述符 命名属性文件位于META-INF/services

<强> descriptor.xml

com.mycompany.actions

<assembly> ... <containerDescriptorHandlers> <containerDescriptorHandler> <handlerName>metaInf-services</handlerName> </containerDescriptorHandler> <containerDescriptorHandler> <handlerName>file-aggregator</handlerName> <configuration> <filePattern>com/mycompany/actions/action.properties</filePattern> <outputPath>com/mycompany/actions/action.properties</outputPath> </configuration> </containerDescriptorHandler> </containerDescriptorHandlers> .... </assembly> 可以在file-aggregator中包含正则表达式以匹配多个文件。以下内容将匹配所有文件名'action.properties'。

filePattern

<filePattern>.+/action.properties</filePattern> metaInf-services分别用于聚合SPI和spring配置文件,而metaInf-spring处理程序将聚合plexus

如果您需要更专业的东西,可以通过实施META-INF/plexus/components.xml并在ContainerDescriptorHandler中定义组件来添加自己的配置处理程序。您可以通过创建一个依赖于META-INF/plexus/components.xml并包含自定义处理程序的上游项目来完成此操作。你可能可以在你正在组装的同一个项目中这样做,但我没有尝试过。处理程序的实现可以在程序集源代码的maven-assembly-plugin包中找到。

<强> CustomHandler.java

org.apache.maven.plugin.assembly.filter.*

然后在package com.mycompany; import org.apache.maven.plugin.assembly.filter.ContainerDescriptorHandler; public class CustomHandler implements ContainerDescriptorHandler { // body not shown }

中定义组件

<强>的components.xml

/src/main/resources/META-INF/plexus/components.xml

最后,您将此添加为您要组装的项目中的程序集插件的依赖项

<强>的pom.xml

<?xml version='1.0' encoding='UTF-8'?>
<component-set>
    <components>
        <component>
            <role>org.apache.maven.plugin.assembly.filter.ContainerDescriptorHandler</role>
            <role-hint>custom-handler</role-hint>
            <implementation>com.mycompany.CustomHandler</implementation>
            <instantiation-strategy>per-lookup</instantiation-strategy>
        </component>
    </components>
</component-set>

并在描述符

中定义handlerName

<强> descriptor.xml

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2.1</version>
    <configuration>
        <descriptors>
            <descriptor>...</descriptor>
        </descriptors>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>com.mycompany</groupId>
            <artifactId>sample-handler</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>
</plugin>

maven-shade-plugin也可以创建'uber-jars',并且有一些资源转换用于处理XML,许可证和清单。

Ĵ

答案 1 :(得分:9)

老问题但在尝试解决类似问题时偶然发现它:程序集插件2.2具有合并文件的功能:http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html#class_containerDescriptorHandler 例如handlerName“metaInf-services”(将连接所有META-INF / services文件),“metaInf-spring”是我所知道的唯一(我个人需要metaInf服务)

答案 2 :(得分:6)

我不知道这个问题的可靠解决方案。但有点环顾四周表明有人created a plugin合并属性文件。从它的外观来看,你需要告诉它要合并哪些文件,这是一件好事,因为你不希望这种方式适用于willy nilly。

假设您已使用dependency-unpack将zip解压缩到已知位置,则可以配置插件以合并每对属性文件并指定适当的目标位置。

您可以使用EL4J中的xmlmerge之类扩展插件来处理XML,如this Javaworld article中所述。

答案 3 :(得分:1)

我还创建了一个合并文件插件,在我的例子中,我使用它将各个项目的SQL文件合并到一个安装程序SQL文件中,该文件可以在单个文件中为我们的应用程序创建所有模式/表/静态数据等, http://croche.googlecode.com/svn/docs/maven-merge-files-plugin/0.1/usage.html

答案 4 :(得分:0)

https://github.com/rob19780114/merge-maven-plugin(在maven central上可用)似乎也可以完成这项工作。 请参阅下面的示例配置

 <plugin>
    <groupId>org.zcore.maven</groupId>
    <artifactId>merge-maven-plugin</artifactId>
    <version>0.0.3</version>
    <executions>
        <execution>
            <id>merge</id>
            <phase>generate-resources</phase>
            <goals>
                <goal>merge</goal>
            </goals>
            <configuration>
              <mergers>
                <merger>
                  <target>${build.outputDirectory}/output-file-1</target>
                  <sources>
                    <source>src/main/resources/file1</source>
                    <source>src/main/resources/file2</source>
                  </sources>
                </merger>
                <merger>
                  <target>${build.outputDirectory}/output-file-2</target>
                  <sources>
                    <source>src/main/resources/file3</source>
                    <source>src/main/resources/file4</source>
                  </sources>
                </merger>
              </mergers>
            </configuration>
        </execution>
    </executions>