2009-10-22 6 views
13

estoy usando Maven y su plug-in de montaje para construir un paquete de distribución de mi proyecto como este:¿Cómo puedo fusionar archivos de recursos en un ensamblaje de Maven?

  • un proyecto reúne a un tiempo de ejecución básico (basado en Felix), con los directorios y los paquetes apropiados, en una postal archivo.
  • bibliotecas de terceros son recogidas en un proyecto cada uno y, o bien convertidos en paquetes OSGi o, si ya son compatibles OSGi, no son más que copian
  • mi propio proyecto consta de varios módulos que están integrados en paquetes OSGi, también .

Ahora, estoy agregando otro proyecto que descomprime el ZIP, coloca todos los otros JAR en los directorios adecuados y los vuelve a empaquetar para su distribución. Ahora, mis paquetes pueden contener archivos de configuración en los que deseo fusionar, en lugar de reemplazar, nombres idénticos en el ensamblado en tiempo de ejecución. ¿Cómo puedo hacer eso?

Los archivos son de texto sin formato (archivos de propiedades), pero podría encontrarse en una situación similar con los archivos XML más adelante.

+0

No sé nada que pueda hacer esto. Dicho esto, no estoy muy acostumbrado a OSGI. Sin embargo, ¿es este un caso de uso "regular"? –

+0

@Pascal - Esto no es específico de OSGi, realmente. No estoy seguro de cuán regular es esto, pero podría imaginar que si quería fusionar WARs u OSGi bundles, me gustaría fusionar archivos web.xml o MANIFEST.MF, respectivamente. Estoy seguro de que hay otras tareas del mismo tipo, pero tal vez haya un enfoque completamente diferente de esto. –

+0

¿Por qué fusionar paquetes OSGI? Soy un gran novato con OSGI, pero ¿no son unidades independientes? Para las WAR, es un poco más claro, pero puedo pensar en muchos problemas con una fusión (por ejemplo, ¿qué pasa si ambas guerras tienen un 'index.jsp', qué pasa si ambas dependen de la misma lib pero con diferentes versiones, etc.) y preferiría considerarlos como unidades independientes también. Parchar un 'web.xml' parece más" realista "(y puede ser útil, por ejemplo, en un contexto de prueba, la carga tiene un objetivo para eso). –

Respuesta

6

No conozco una solución robusta a este problema. Pero un poco de mirar alrededor muestra que alguien tiene created a plugin para fusionar archivos de propiedades. A simple vista, debe indicarle qué archivos fusionar, lo que es bueno ya que no quiere que esto se aplique de todas maneras.

Suponiendo que ha usado dependence-unpack para descomprimir el archivo zip en una ubicación conocida, sería un caso de configurar el complemento para fusionar cada par de archivos de propiedades y especificar la ubicación de destino adecuada.

Puede ampliar el complemento para manejar XML utilizando algo como xmlmerge de EL4J, como se describe en this Javaworld article.

+0

Genial, analizaremos eso. –

+0

¡El plugin parece funcionar muy bien! –

+0

Me alegro de que funcione, podría ser útil para mí también –

1

También he creado un complemento de archivos de fusión, en mi caso lo uso para combinar archivos SQL de varios proyectos en un único archivo SQL instalador que puede crear todos los esquemas/tablas/datos estáticos, etc. para nuestras aplicaciones en un solo archivo, http://croche.googlecode.com/svn/docs/maven-merge-files-plugin/0.1/usage.html

+0

¿Por qué veo http://croche.googlecode.com/svn/docs/maven-merge-files-plugin/0.4/usage.html como texto sin formato y no como HTML? – xmedeko

20

Expandiendo un poco la respuesta de Juergen para aquellos que tropiezan con esto, el containerDescriptorHandler en el descriptor puede tomar cuatro valores (v2.3), estos son metaInf-services, file-aggregator, plexus, metaInf-spring. Está un poco enterrado en el código (se encuentra en el paquete org.apache.maven.plugin.assembly.filter), pero es posible agregar archivos de configuración/propiedades.

Aquí hay un descriptor de ejemplo que agrega los archivos de propiedad META-INF/services y ubicados en 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> 

El file-aggregator puede contener una expresión regular en la filePattern para que coincida con varios archivos. Lo siguiente coincidiría con todos los nombres de archivos 'action.properties'.

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

El metaInf-services y metaInf-spring se utilizan para la agregación y la configuración de la primavera SPI archivos, respectivamente, mientras que el manejador se plexus agregar META-INF/plexus/components.xml juntos.

Si necesita algo más especializado, puede agregar su propio controlador de configuración implementando ContainerDescriptorHandler y definiendo el componente en META-INF/plexus/components.xml. Puede hacerlo creando un proyecto ascendente que tenga una dependencia en maven-assembly-plugin y contenga su controlador personalizado. Es posible hacer esto en el mismo proyecto que estás armando, pero no lo intenté. Las implementaciones de los controladores se pueden encontrar en el paquete org.apache.maven.plugin.assembly.filter.* del código fuente del ensamblaje.

CustomHandler.java

package com.mycompany; 

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

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

entonces definir el componente en /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> 

Finalmente se agrega esto como una dependencia en el plug-in de montaje en el proyecto que desea ensamblar

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> 

y definir el handlerName en el descriptor de

descriptor.xml

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

El maven-shade-plugin también puede crear 'uber-tarros' y tiene algunas transformaciones de recursos para manejar XML, licencias y manifiestos.

J

+2

Respuesta impresionante; No pude encontrar esto debidamente documentado en ningún otro lado. – ctrueden

+0

Todo eso solo para especificar 'metaInf-services'? No necesito ni quiero un archivo 'descriptor.xml'. ¿Hay alguna manera de simplemente indicar el controlador 'metaInf-services' en' 'en el POM> –

0

https://github.com/rob19780114/merge-maven-plugin (disponible en experta en el centro) también parece hacer el trabajo. Vea a continuación un ejemplo de configuración

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

Cuestiones relacionadas