Hacer un zip para distribuir

De ChuWiki
Saltar a: navegación, buscar

El plugin Assembly

Assembly es un plugin de maven que permite generar un zip con nuestros jar, ficheros de configuración, iconos y lo que necesitemos para poder distribuirlo. De esta forma, llevándonos el zip y desempaquetándolo tendremos nuestro programa listo par ejecutar.

Zips predefinidos en Assembly

El plugin assembly de Maven tiene varios tipos de zip predefinidos. Las siguientes ejecuciones

mvn assembly:assembly -DdescriptorId=bin
mvn assembly:assembly -DdescriptorId=jar-with-dependencies
mvn assembly:assembly -DdescriptorId=src

El primero crea un jar sin más. El segundo un jar con todos los jar de los que depende. El tercero uno con los fuentes.

Configurar nuestro propio zip

Si no nos gustan los predefinidos, podemos configurar assembly-maven para que genere los zip con lo que necesitemos.

Para ello, en el directorio del proyecto, creamos un fichero src/main/assembly/dep.xml en el que indicamos qué cosas queremos que se empaqueten en el zip. Puede tener esta pinta

<assembly>
   <id>bin</id>
   <formats>
      <!-- Formatos en el que queremos el zip -->
      <format>tar.gz</format>
      <format>tar.bz2</format>
      <format>zip</format>
   </formats>
   <!-- Ahora que cosas queremos -->
   <fileSets>
     <!-- Nuestros ficheros de configuracion guardados en src/main/config-->
     <fileSet>
        <directory>src/main/config</directory>
        <!-- Queremos que esten en un subdirectorio CONFIG dentro del zip -->
        <outputDirectory>/CONFIG</outputDirectory>
     </fileSet>
     <fileSet>
         <!-- Queremos los jar generados en target que se incluyan en el
              directorio Jar dentro del zip -->
         <directory>target</directory>
         <outputDirectory>/Jar</outputDirectory>
         <includes>
            <include>*.jar</include>
         </includes>
     </fileSet>
   </fileSets>
   <!-- Queremos incluir los jar de los que dependemos -->
   <dependencySets>
      <dependencySet>
         <!-- Queremos los jar dentro de un directorio Jar dentro del zip -->
         <outputDirectory>/Jar</outputDirectory>
         <!-- Que añada todo lo necesario para la ejecución -->
         <scope>runtime</scope>
      </dependencySet>
   </dependencySets>
</assembly>

Luego, en el pom.xml debemos darle la posibilidad de hacer el zip

<project>
...
   <build>
      ...
      <plugins>
      ...
         <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
               <descriptors>
                   <!-- Sitio en el que esta el fichero anterior -->
                   <descriptor>src/main/assembly/dep.xml</descriptor>
               </descriptors>
            </configuration>
         </plugin>
      </plugins>
   </build>
</project>

Esto creara en el directorio target del proyecto los tres zip indicados antes (zip, tar.gz y tar.bz2)


Problema con los SNAPSHOT

Actualmente hay un problema cuando se dan estas tres circunstancias:

  • Generamos un jar con fichero de manifiesto y Class-Path con maven
  • Intentamos hacer además un zip de distribución con assembly
  • Y tenemos implicadas versiones snapshot.

Una versión snapshot es una versión de un jar que todavía está en desarrollo, por lo que cambia con frecuencia. En la versión se suele poner algo como esto fichero-1.0-SNAPSHOT.jar . Maven interpreta ese trozo "SNAPSHOT" como algo que está en desarrollo y cada vez que subimos con deploy uno de estos jar a un repositorio, cambia SNAPSHOT por un timestamp = fecha.hora-numero, como por ejemplo 20080322.110711-2.

Maven, cuando generamos un jar con fichero de manifiesto y Class-Path, pondrá los jar de los que dependemos con la palabra SNAPSHOT. Es decir, dirá que depende de fichero-1.0-SNAPSHOT.jar

Assembly, cuando nos pone los jar en el zip, mete dentro el jar pero con el timestamp fecha.hora-numero. Por ello, al intentar ejecutar, se buscará un fichero-1.0-SNAPSHOT.jar y no se encontrará, porque existe un fichero-1.0-20080322.110711-2.jar.

Actualmente esta discrepancia está en vías de ser corregida, pero hasta entonces podemos aprovechar las capacidades de assembly para evitar este problema. Assembly permite que cambiemos los nombres de los jar que va a meter a nuestro gusto. Para ello, ponemos algo como esto en nuestro fichero dep.xml

   <dependencySets>
      <dependencySet>
	 <outputDirectory>/Jar</outputDirectory>
         <outputFileNameMapping>${artifact.artifactId}-${artifact.baseVersion}${dashClassifier?}.${artifact.extension}</outputFileNameMapping>
        <scope>runtime</scope>
      </dependencySet>
   </dependencySets>

El tag <outputFileNameMapping> nos permite poner el nombre de los jar como queramos. Para ello podemos usar variables predefinidas como se muestra en el ejemplo

  • ${artifact.artifactId} es el nombre del artifact maven, que coincide con el nombre del jar sin extensión y sin versión
  • ${artifact.baseVersion} es la versión, pero como SNAPSHOT. Si usasemos ${artifact.version} entonces obtendríamos el timestamp fecha.hora-numero
  • ${dashClassfier?} es un trozo que se puede poner detrás de la versión en algunas ocasiones. El interrogante indica que puede no existir.
  • ${artifact.extension} es la extensión del fichero.


Enlaces externos