Как объединить файлы ресурсов в сборке Maven?

Я использую Maven и его плагин сборки для сборки дистрибутива моего проекта следующим образом:

  • один проект собирает базовую среду выполнения (на основе Felix) с соответствующими каталогами и пакетами в ZIP файле.
  • сторонние библиотеки собираются по одному проекту и преобразуются в пакеты OSGi или, если они уже совместимы с OSGi, они просто копируются
  • мой собственный проект состоит из нескольких модулей, которые также встроены в пакеты OSGi.

Теперь я добавляю еще один проект, который распаковывает ZIP, выкидывает все остальные JAR в соответствующие каталоги и переупаковывает его для распространения. Теперь мои пакеты могут содержать файлы конфигурации, в которые я хочу объединиться, вместо замены идентично названных в сборке времени выполнения. Как это сделать?

Файлы представляют собой обычный текст (файлы свойств), но позже я могу столкнуться с аналогичной ситуацией с файлами XML.

Ответы

Ответ 1

Я не знаю о надежном решении этой проблемы. Но немного оглядываясь, показывает, что кто-то создал плагин для объединения файлов свойств. По внешнему виду вам нужно сказать, какие файлы слить, что хорошо, поскольку вы не хотите, чтобы это применялось волей-неволей.

Предполагая, что вы использовали папку с зависимостями, чтобы распаковать zip в известное местоположение, было бы целесообразно настроить плагин для объединения каждой пары файлов свойств и указания соответствующего целевого местоположения.

Вы можете расширить плагин для обработки XML, используя что-то вроде xmlmerge из EL4J, как описано в этой статье Javaworld.

Ответ 2

Развернув бит на Juergen, ответьте на тех, кто спотыкается на это - containerDescriptorHandler в дескрипторе может принимать четыре значения (v2.3), это metaInf-services, file-aggregator, plexus, metaInf-spring, Он немного похож на код (находится в пакете org.apache.maven.plugin.assembly.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-services и metaInf-spring используются для агрегирования SPI и spring файлов конфигурации соответственно, в то время как обработчик plexus объединит META-INF/plexus/components.xml.

Если вам нужно что-то более специализированное, вы можете добавить свой собственный обработчик конфигурации, реализовав containerDescriptorHandler и определяя компонент в META-INF/plexus/components.xml. Вы можете сделать это, создав восходящий проект, который имеет зависимость от maven-assembly-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>

и определить имя обработчика в дескрипторе

descriptor.xml

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

maven-shade-plugin также может создавать "uber-jars" и имеет некоторые преобразования ресурсов для обработки XML, лицензий и манифестаций.

J

Ответ 3

Старый вопрос, но наткнулся на него, пытаясь решить аналогичную проблему: Assembly plugin 2.2 имеет возможности объединить файлы: http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html#class_containerDescriptorHandler например handlerName "metaInf-services" (будет конкатенировать все файлы META-INF/services), "metaInf- spring" - это единственные, о которых я знаю (мне лично нужны метаинформации)

Ответ 4

Ive также создал плагин слияния файлов, в моем случае я использую его для объединения файлов SQL из разных проектов в один файл SQL установщика, который может создавать все схемы/таблицы/статические данные и т.д. для наших приложений в одном файле, http://croche.googlecode.com/svn/docs/maven-merge-files-plugin/0.1/usage.html

Ответ 5

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>