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

发布于 2024-08-08 12:31:51 字数 366 浏览 5 评论 0原文

我使用 Maven 及其组装插件来构建我的项目的分发包,如下所示:

  • 一个项目在 ZIP 文件中组装了一个基本运行时(基于 Felix)以及适当的目录和捆绑包。
  • 第三方库分别收集在一个项目中,然后转换为 OSGi 捆绑包,或者如果它们已经与 OSGi 兼容,则直接复制它们。
  • 我自己的项目也包含几个内置于 OSGi 捆绑包中的模块。

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

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

I'm using Maven and its assembly plugin to build a distribution package of my project like this:

  • one project assembles a basic runtime (based on Felix), with the appropriate directories and bundles, in a ZIP file.
  • third-party libraries are collected in one project each and either converted to OSGi bundles or, if they are already OSGi compatible, they are just copied
  • my own project consists of several modules that are built into OSGi bundles, too.

Now, I'm adding another project that unpacks the ZIP, drops all the other JARs into the proper directories, and repackages it for distribution. Now, my bundles might contain configuration files that I want to merge into, rather than replacing, identically named ones in the runtime assembly. How do I do that?

The files are plain text (property files), but I might run into a similar situation with XML files later.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

萌辣 2024-08-15 12:31:52

对于那些偶然发现这一点的人,对 Juergen 的答案进行了一些扩展 - 描述符中的 containerDescriptorHandler 可以采用四个值 (v2.3),这些是 metaInf-services文件聚合器plexusmetaInf-spring。它有点隐藏在代码中(在 org.apache.maven.plugin.assemble.filter 包中找到),但可以聚合配置/属性文件。

下面是一个示例描述符,它聚合了 META-INF/services 和
命名属性文件位于 com.mycompany.actions 中。

descriptor.xml

<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 可以在 filePattern 中包含正则表达式来匹配多个文件。以下内容将匹配所有文件名“action.properties”。

<filePattern>.+/action.properties</filePattern>

metaInf-servicesmetaInf-spring 用于聚合SPI 和 spring 配置文件,而 plexus 处理程序会将 META-INF/plexus/components.xml 聚合在一起。

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

CustomHandler.java

package com.mycompany;

import org.apache.maven.plugin.assembly.filter.ContainerDescriptorHandler;

public class CustomHandler implements ContainerDescriptorHandler {
    // body not shown
}

中定义组件

/src/main/resources/META-INF/plexus/components.xml components.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>

然后 将其添加为对要组装的项目中的组装插件的依赖项

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

中定义 handlerName

并在描述符descriptor.xml

...
<containerDescriptorHandler>
    <handlerName>custom-handler</handlerName>
</containerDescriptorHandler>
...

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

J

Expanding a bit on Juergen's answer for those who stumble on this - the containerDescriptorHandler in the descriptor can take four values (v2.3), these are metaInf-services, file-aggregator, plexus, metaInf-spring. It's a bit buried in the code (found in the package org.apache.maven.plugin.assembly.filter) but it is possible to aggregate config/properties files.

Here's an example descriptor that aggregates the META-INF/services and
named property files located in com.mycompany.actions.

descriptor.xml

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

The file-aggregator can contain a regular expression in the filePattern to match multiple files. The following would match all files names 'action.properties'.

<filePattern>.+/action.properties</filePattern>

The metaInf-services and metaInf-spring are used for aggregating SPI and spring config files respectively whilst the plexus handler will aggregate META-INF/plexus/components.xml together.

If you need something more specialised you can add your own configuration handler by implementing ContainerDescriptorHandler and defining the component in META-INF/plexus/components.xml. You can do this by creating an upstream project which has a dependency on maven-assembly-plugin and contains your custom handler. It might be possible to do this in the same project you're assembling but I didn't try that. Implementations of the handlers can be found in org.apache.maven.plugin.assembly.filter.* package of the assembly source code.

CustomHandler.java

package com.mycompany;

import org.apache.maven.plugin.assembly.filter.ContainerDescriptorHandler;

public class CustomHandler implements ContainerDescriptorHandler {
    // body not shown
}

then define the component in /src/main/resources/META-INF/plexus/components.xml

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

Finally you add this as a dependency on the assembly plugin in the project you wish to assemble

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

and define the handlerName in the descriptor

descriptor.xml

...
<containerDescriptorHandler>
    <handlerName>custom-handler</handlerName>
</containerDescriptorHandler>
...

The maven-shade-plugin can also create 'uber-jars' and has some resource transforms for handling XML, licences and manifests.

J

罪#恶を代价 2024-08-15 12:31:52

老问题,但在尝试解决类似问题时偶然发现了它:Assembly plugin 2.2 has features to merge files:

Old question but stumbled over it while trying to solve similar problem: Assembly plugin 2.2 has capabilities to merge files: http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html#class_containerDescriptorHandler
e.g. handlerName "metaInf-services" (will concat all META-INF/services files), "metaInf-spring" are the only ones I know of (I personally needed metaInf-services)

空城仅有旧梦在 2024-08-15 12:31:52

我不知道这个问题的可靠解决方案。但环顾四周发现有人有 创建了一个插件来合并属性文件。从它的外观来看,您需要告诉它要合并哪些文件,这是一件好事,因为您不希望随意应用此操作。

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

您可以使用 EL4J 中的 xmlmerge 之类的东西来扩展插件来处理 XML,如 这篇 Javaworld 文章

I don't know of a robust solution to this problem. But a bit of looking around shows that somebody has created a plugin to merge properties files. By the look of it you need to tell it which files to merge, which is a good thing as you don't want this applied willy nilly.

Assuming you have used dependency-unpack to unpack the zip to a known location, it would be a case of configuring the plugin to merge each pair of properties files and specify the appropriate target location.

You could extend the plugin to handle XML by using something like xmlmerge from EL4J, as described in this Javaworld article.

许你一世情深 2024-08-15 12:31:52

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

Ive also created a merge files plugin, in my case i use it to merge SQL files from various projects into a single installer SQL file which can create all the schemas/tables/static data etc for our apps in a single file, http://croche.googlecode.com/svn/docs/maven-merge-files-plugin/0.1/usage.html

洋洋洒洒 2024-08-15 12:31:52

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

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

https://github.com/rob19780114/merge-maven-plugin (available on maven central) also seems to do the job.
See below for an example configuration

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文