Как объединить файлы ресурсов в сборке 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>