Visit Linkwerk.com

Das maven-release-plugin und Assemblies

Oft sind es die kleinen Dinge im Leben. Da hat man ein Problem, man frisst sich durch seitenweise Foren, Dokumentation, ist kurz vorm Verzweifeln, und schlussendlich lag die Lösung die ganze Zeit direkt vor einem. Aber von vorne …Seit einer Weile werden Releases unser Software-Projekte ausschliesslich mit dem maven-release-plugin und der Hilfe von Hudson gebaut. Das verhindert das klassische “Bei mir liefs aber …” und ähnliche Probleme und vereinheitlicht ausserdem den Release-Prozess für all unsere Projekte (zumindest sofern in Java). So vermeiden wir unnötige Fehlerquellen und haben unseren Entwicklungs-Prozess signifikant verbessert. So weit so gut.

Das Plugin erzeugt bei einem Release drei Maven-Artefakte (POM, Sources, Javadoc), die dann alle in unserem Maven-Release-Repository (mit Apache Archiva) landen. Eines unserer Projekte beinhaltet aber selbst überhaupt keinen Code, sondern dient nur als Aggregations-Projekt um mit Hilfe des maven-assembly-plugins ein Distributions-Paket zu bauen. Dazu lässt sich das passende Goal des Plugins an die package-Phase binden:

<plugin>
 <artifactId>maven-assembly-plugin</artifactId>
 <version>2.2-beta-4</version>
 <configuration>
  <descriptors>
   <descriptor>src/main/assembly/distribution.xml</descriptor>
  </descriptors>
  <finalName>${pom.artifactId}-${pom.version}</finalName>
  <appendAssemblyId>false</appendAssemblyId>
  <tarLongFileMode>warn</tarLongFileMode>
 </configuration>
 <executions>
  <execution>
   <id>dist-assembly</id>
   <phase>package</phase>
   <goals>
    <goal>assembly</goal>
   </goals>
  </execution>
 </executions>
</plugin>

Wenn dann in Hudson

mvn release:prepare release:perform release:clean

ausgeführt wird, wird das angestrebte tar.gz auch anstandslos erzeugt, genauso anstadlos wird es aber in der deploy-Phase ignoriert und landet somit nicht, wie beabsichtigt, in unserem Release-Repository.

Wie kann man also dem Release-Plugin beibringen, das per Assembly erzeugte Paket ebenfalls zu deployen ? Recherche bezüglich des Plugins führt in Leere, bzw. man lernt recht schnell, dass das Plugin nichts anderes tut als die Standard-Goals (Test, Package, Deploy, …) auszuführen. Der nächste Schritt führt einen also zum maven-deploy-plugin und in der Tat kann der bastelfreudige Entwickler mit Hilfe des deploy-file-Goals einzelne Datei mittels eigener Executions in Remote-Repositories transferieren.

Noch während des Kampfes mit der passenden Konfiguration stiess ich dann auf das build-helper-maven-plugin. Damit kann man per attach-artifact Files zur Liste der Artefakte hinzufügen die dann während der install- und deploy-Phase verarbeitet werden:

<plugin>
 <groupId>org.codehaus.mojo</groupId>
 <artifactId>build-helper-maven-plugin</artifactId>
 <version>1.3</version>
 <executions>
  <execution>
   <id>attach-distribution</id>
   <phase>package</phase>
   <goals>
    <goal>attach-artifact</goal>
   </goals>
   <configuration>
    <artifacts>
     <artifact>
      <file>target/${pom.artifactId}-${pom.version}.tar.gz</file>
      <type>tar.gz</type>
     </artifact>
    </artifacts>
   </configuration>
  </execution>
 </executions>
</plugin>

Vorerst gklücklich über die gefundene und vor allem funktionierende Lösung stellte sich kurz darauf die blanke Ernüchterung ein. Dank Anders Hammar, der auf eine entsprechende Frage in der maven-user-Mailingliste antwortete weiss ich nun dass ich der besten und elegantesten Lösung am Anfang schon am nächsten war und mich letzlich ständig weiter von ihr enfernte … Nur das Ziel bei der Verwendung des assembly-plugins stimmte nicht, denn dort ist für genau diesen Use-Case das single-Goal vorgesehen:

  <execution>
   <id>dist-assembly</id>
   <phase>package</phase>
   <goals>
    <goal>single</goal>
   </goals>
  </execution>

Letzlich zählt aber die Tatsache dass wir jetzt mit der einfachsten und elegantesten Lösung am Start sind, und man kann eigentlich nur mit zwei klassischen Gemeinplätzen schliessen:

Man lernt nie aus, und oft sind es die kleinen Dinge im Leben.

In diesem Fall satte 8 Characters :)


Leave a Reply