Maven in grossen Softwareprojekten
von Markus Eisele

Softwareprojekte sind immer eine Herausforderung. Je größer Projekte werden, desto mehr bewahrheitet sich diese alte Weisheit. Ein Themenkomplex wird dabei immer auf besonders dramatische Weise unterschätzt: Buildmanagement und Packaging in Java Projekten. Nachdem Apache Ant diesen Bereich Jahrelang versuchte in geregelte Bahnen zu lenken etabliert sich seit ein paar Jahren auch Apache Maven als zunehmend interessante Alternative.

Hervorgegangen ist Maven aus dem Apache Jakarta Turbine Projekt. Es wurde mit dem Ziel aus der Taufe gehoben, das komplexe und verstreute, Ant basierte Buildmanagement der verschiedenen Subprojekte zu reorganisieren und zu vereinfachen. Hauptsächliches Ziel dabei war es, gemeinsame Bibliotheken effektiv wiederzuverwenden und einen standardisierten Weg zu haben um ein stabiles Turbine Projekt erstellen zu können. Vor diesem Hintergrund wurden bereits in 2002 etliche Ant Buildskripte von allen Projekten durch einen konsistenten Maven Build ersetzt. Damit ist auch klar, was "Maven" als Wort bedeutet. Es ist ein Wort aus dem Jiddischen, was soviel bedeutet, wie "Sammler von Wissen".

Anspruch und Ziel von Maven

Mit diesem vergleichsweise hohen Anspruch tritt Maven auch an um Java Projekte besser zu machen. Dabei geht es primär um einen einfachen, standardisierten Buildprozess. Ergänzend dazu stellen eine Unmenge von Erweiterungen Informationen über die jeweiligen Projekte bereit und sorgen damit für die notwendige Transparenz über alle Subprojekte hinweg. Quasi nebenbei bringt Maven damit auch eine anständige Sammlung von Richtlinien und Regelungen im Sinne von "Best Practices" mit. Dazu gehören vor allem die saubere Integration von Unittests und das Bauen von verschiedenen Archivtypen (bspw. *.war, *.jar, etc.). In Summe ist Maven also das bessere Ant. Vor allem vor dem Hintergrund, dass es sich nicht nur um ein weiteres Build-Werkzeug handelt, sondern vor allem deshalb, weil es sich um einen standardisierten Buildprozess handelt. Oberstes Ziel ist und war dabei immer, dass das Wissen um den eigentlichen Build und Packaging Prozess nicht mehr nur bei ein paar Spezialisten verbleibt, sondern dass alle beteiligten Entwickler in der Lage sind, die Beschreibungen für den Prozess zu lesen und zu verändern. Damit können alle an derartigen Projekten beteiligten Entwickler ohne Probleme von einem ins nächste Projekt wandern, ohne sich erst orientieren zu müssen. Neben dem eigentlichen Build gilt dieses mit Maven auch für die Modultests und die Dokumentation. Quasi nebenbei erlaubt die konsequente Modulstrategie auch die Wiederverwendung von einzelnen Komponenten bzw. Modulen.

Setup und Konfiguration

Das Abenteuer Maven beginnt mit dem Download der aktuellsten Version von den Projektwebseiten. Danach wird das ZIP einfach in ein beliebiges Verzeichnis auf der Platte entpackt. Dies Verzeichnis ist von nun an als <MVN_HOME> bekannt. Nimmt man das <MVN_HOME>/bin noch in den Pfad auf, kann man schon starten. Der Aufruf "mvn -version" liefert als Ausgabe direkt einen Überblick über die aktuelle Version von Maven, Java und dem eingesetzten Betriebssystem Nach dem Start eines Komandos versucht Maven sich die für das Ausführen des Kommandos notwendigen Bibliotheken von seinem zentralen Server aus dem Internet herunterzuladen. Zumeist gelingt dies ohne weitere Probleme. Ist zum Zugang ins Internet ein Proxy Server notwendig, dann muss dieser entsprechend konfiguriert werden. Dies gelingt am elegantesten durch die Anpassung der zentralen Maven settings.xml Datei. Diese findet man im <MVN_HOME>/conf Verzeichnis. Im Abschnitt <proxies> kann man einfach seinen notwendigen Proxy-Server hinzu konfigurieren:
  <proxy>
      <id>optional</id>
      <active>true</active>
      <protocol>http</protocol>
      <host>proxy.company.de</host>
      <port>8084</port>
      <nonProxyHosts>localhost</nonProxyHosts>
    </proxy>
    
Die notwendigen Bibliotheken werden dann unter Zuhilfenahme des Proxys aus dem Netz geladen. Zum Glück ist dies nicht für jedes Ausführen von Maven notwendig. Einmal geladen, werden abhängige Bibliotheken von Maven auf dem Entwicklerrechner vorgehalten. Dies geschieht im Home-Verzeichnis des jeweiligen Nutzers unter ~\.m2\repository. Was auf den ersten Blick nach dem Anlegen des neuen Moduls noch recht überschaubar aussieht, kann allerdings mit wachsenden Abhängigkeiten und längerer Maven Verwendung durchaus mächtig wachsen. Ein gut 500MB großes Repository ist keine Seltenheit. Es empfiehlt sich, in der settings.xml den Pfad zum <localRepository> anzupassen und ein Laufwerk zu verwenden, welches mehr Luft hat, als beispielsweise die typische C:\ Partition eines Windowsrechners. Wer bei mehr als einem oder deutlich komplexeren maven-basierten Projekt mitarbeitet kann auch über die Verwendung von sogenannten <profiles> nachdenken. Dieser Konfigurationsabschnitt in der settings.xml ermöglicht die komplett separate Definition von verschiedenen Build-Prozess-Profilen. Mit diesem Mechanismus kann man dann nicht nur für unterschiedliche Umgebungen (Test, Produktion, et cetera) sondern auch für verschiedene Projekte ein jeweils einheitliches Profil definieren.

Grundlegendes Arbeiten mit Maven

Nun gilt es, das erste Beispielprojekt aufzusetzen. Das gelingt am besten durch das Ausführen des zugehörigen Maven Kommandos in einer DOS-Kommandobox: mvn archetype:create -DgroupId=de.heise.ix -DartifactId=maven-beispiel An der Stelle im Verzeichnisbaum, wo das Kommando ausgeführt wurde, entstand nunmehr ein neues Verzeichnis mit dem namen "maven-beispiel". Auf der Ebene "src" finden sich die beiden Verzeichnisse "main" und "test". In "main" werden alle Java Sourcen hinterlegt. In "Test" gehören die relevanten Junit Testfälle. Grundsätzlich kann man mit diesem ersten Modul bereits anfangen zu entwickeln. Vor dem Start sollte man allerdings noch einen Blick in die pom.xml -Datei werfen. In dieser werden alle projektspezifischen Einstellungen von Maven verwaltet. In diesem ersten Beispiel ist sie noch recht übersichtlich.
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>de.heise.ix</groupId>
  <artifactId>maven-beispiel</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>maven-beispiel</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
Neben den gemachten Angaben zur Version und zum eigentlichen Modul (artifact) finden sich in der pom.xml vor allem die weiteren Abhängigkeiten zu anderen Bibliotheken oder Modulen. Im Falle unseres Beispiels ist das eine Abhängigkeit (Dependency) zum Projekt Junit in der Version 3.8.1. Neben den Abhängigkeiten ist vor allem die Art des Moduls wichtig. Diese wird über das Tag <packaging> gesetzt. Im Falle des Beispiels steht dort "jar" als Typ. Weiterhin sind noch maven-plugin, ejb, war, ear, rar, par und pom möglich. Dabei handelt es sich jeweils um eine spezielle Art des Packaging, was von maven durchgeführt wird. Beim Typ "war" wird beispielsweise eine JEE Webanwendung gebaut. Besonders ist der Typ "pom". Er definiert ein übergreifendes Konfigurationsmodul. Dies ist wichtig, will man ein Projekt aus mehreren Submodulen aufbauen. Erst wenn man in dem Beispiel den Typ "pom" gesetzt hat, kann man dies auch tun. Wechselt man in den erstellen Ordner "maven-beispiel" und führt den folgenden Befehlt aus: mvn archetype:create -DgroupId=de.heise.ix -DartifactId=modul1 Wird ein neues Modul-Projekt unterhalb des maven-beispiels angelegt. In der übergreifenden pom.xml findet sich dann auch der neue, zusätzliche Eintrag:
<modules>
    <module>modul1</module>
  </modules>
  
Analog dazu lassen sich nun beliebig strukturierte und hierarchisch aufgebaute Projekt- und Modulstrukturen umsetzen. Im Sinne der Modulfindung eignet sich ein Blick auf die Komponenten eines Systems. Es hat sich herausgestellt, dass grade die Komponenten, welche fachliche Anforderungen gesamthaft behandeln geeignete Kandidaten für separate Module sind. Im Sinne des Softwaredesigns kann man hier tatsächlich auch von Softwarekomponenten reden. Klassisch sind diese bereits durch geeignete Packagestrukturen vorgegeben. Findet man bereits zum Projektstart einen entsprechenden Modulschnitt, dann hat man Abhängigkeiten zwischen Komponenten per Deklaration von Anfang an im Griff. Hat man nun mehr als ein weiteres Modul hinzugefügt und will man beispielsweise aus modul1 auf modul2 zugreifen, dann ist dies nicht ohne weiteres Möglich. Nachdem beide Module ihre Sourcen und auch die Kompilate in verschiedenen Verzeichnissen haben, muss man Maven zuerst mitteilen, wie die Abhängigkeiten zwischen den Modulen aussehen. Dazu wird in dem Modul, welches ein oder mehrere andere Module verwenden will eine entsprechende Abhängigkeit in die pom.xml eingetragen. Will unser modul1 bspw. auf das modul2 zugreifen, dann muss in der pom.xml von modul1 folgendes eingetragen werden:
<dependency>
  <groupId>de.heise.ix</groupId>
  <artifactId>modul2</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>
Dies führt dazu, dass die Abhängigkeit bei allen Aktionen auf modul1 entsprechend berücksichtigt wird. Muss modul1 beispielsweise kompiliert werden, dann wird zuerst modul2 kompiliert und dessen Kompilate können dann in modul1 verwendet werden. Gleiches gilt natürlich auch für die weitere Vererbung von Bibliotheken. D.h. wenn modul2 eine weitere Bibliothek verwendet, dann kommt diese über die Abhängigkeit auch in das modul1. Nicht unerwähnt bleiben sollte die Tatsache, dass man neben Testfällen und den Java Sourcen auch noch beliebige andere Ressourcen in einem Modul verpacken kann. Dazu erstellt man einfach unterhalb von "main" noch ein weiteres Verzeichnis "resources". Alle Konfigurationen oder ähnliche Dinge, welche noch benötigt werden können hier hinterlegt werden. Beim Einpacken durch Maven kommen die ebenfalls mit ins Artefakt. Was nun noch fehlt ist eine Integration in eine integrierte Entwicklungsumgebung (IDE). Auch dies unterstützt Maven selbstverständlich. Mit dem Kommando mvn eclipse:eclipse generiert Maven die für Eclipse notwendigen .classpath und .project Dateien in die Module hinein. Dem Import in eine Eclipse Workarea steht damit nichts mehr im Wege. Neben Eclipse werden auch IntelliJ, NetBeans und sogar der IBM Rational Application Developer (RAD) unterstützt. Durch die Konfiguration des entsprechenden Plugins kann man eine nahtlose Integration in die jeweilige Entwicklungsumgebung erreichen. Das folgende Beispiel zeigt, wie man das Ausgabeverzeichnis des Eclipse Build auf einen beliebigen Wert setzt:
<build>
[...]
  <pluginManagement>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-eclipse-plugin</artifactId>
        <configuration>
          <outputDirectory>target-eclipse</outputDirectory>
        </configuration>
      </plugin>
    </plugins>
  </pluginManagement>
[...]
</build>
Abschließend bleibt nur noch die Frage, wie man denn mit Maven seine Sourcen compiled. Dazu gibt es ebenfalls ein Maven Komando. Mit mvn compile rennt Maven los und kompiliert alle Sourcen von allen Modulen in den zugehörigen "target" Ordner. Aufgeräumt wird mit mvn clean. Dabei werden alle generierten Dateien wieder gelöscht. Ein letztes Kommando soll den bunten Reigen abrunden. Mit mvn install wird das generierte und verpackte Artefakt in das lokale Repository geschoben. Damit steht es anderen Projekten unter seiner Id und Gruppenzugehörigkeit, wie definiert zur Verfügung.

Herausforderungen in großen Projekten

Einen Vergleich mit Ant braucht Maven bis hierher überhaupt nicht zu scheuen. Ohne eine Zeile komplizierten XML Code wurde eine komplette Modulstruktur aufgebaut und diese lässt sich auch über einfachste Mittel schnell und konsequent wiederholbar zu einem Java Packet schnüren. Die richtigen Herausforderungen für Maven stellen große Projekte dar. Hierbei handelt es sich zumeist nicht nur um ein paar Module sondern schnell mal um 30 und mehr. Auch sind in den Teams selten weniger als zehn Entwickler beteiligt. Kommt nun noch eine besondere Ablaufumgebung (IBM WebSphere oder Bea Weblogic) oder eine vorgegebene IDE (IBM RAD oder Weblogic Workshop) hinzu, dann muss man viel mehr Probleme lösen, als man vorher dachte. Den Anfang machen die Namenskonventionen bei den Modulen. Mit einer einfachen und flachen Hierarchie kommt man nicht sehr weit. Es lohnt sich also durchaus eine Modulhierarchie über Systeme, Subsysteme und Komponenten aufzubauen. Auch wenn die Verzeichnisstruktur für die Projekte damit nicht einfacher wird, sind die Verwaltung der Abhängigkeiten und die Navigation in den Strukturen damit deutlich einfacher. [Abb.2 - dir2.psd // Komplexere Verzeichnisstruktur] Wichtig zu wissen ist auch, dass <artifactId> und <name> der jeweiligen Module deutlich unterschiedliche Verwendungszwecke haben. Die artifactId sollte ohne Sonderzeichen in zusammenhängenden Begriffen vergeben werden. Sie wird meist auch als Verzeichnisname verwendet. Als Name kann ein beliebiger verwendet werden. Hier sind auch Leer- und Sonderzeichen erlaubt. Dennoch ist es Empfehlenswert beides auch inhaltlich nicht deutlich voneinander zu trennen. Beispielsweiser wird beim Starten von Maven in der Reactor-Übersicht immer der Name angezeigt. Ist dieser nicht zu unterschiedliche von der artifactId, kann man auf einen Blick schnell checken, ob alle relevanten Module auch wirklich im Build berücksichtigt werden. Ein besonderes Problem in großen Projekten stellen nicht nur in Interkomponentenabhängigkeiten sondern vor allem auch die Bibliotheksabhängigkeiten dar. In der <dependencies> Sektion der jeweiligen Modul pom.xml kann nahezu beliebig alles an OpenSource Projekten angegeben werden, was der Markt so hergibt. Dazu bedarf es eines dreizeiligen Eintrages. Am Beispiel der Facelets Spezifikation kann das so aussehen:
<dependency>
		<groupId>com.sun.facelets</groupId>
		<artifactId>jsf-facelets</artifactId>
		<version>1.1.14</version>
	</dependency>
	
Erlaubt man dies in jedem beliebigen Modul zu jeder Zeit, dann überlebt man grad in größeren Teams immer wieder Überraschungen. Auch wenn die pom.xml Dateien zusammen mit den Sourcen in das Versionsverwaltungssystem gehören kann es schon einmal vorkommen, dass die letzte generierte Eclipse Integration (.classpath) nicht mehr zu den in den pom.xml konfigurierten Abhängigkeiten passt. Direktes Ergebnis hieraus ist es, dass zwar Maven die Module kompilieren kann, diese im Eclipse aber nicht mehr lauffähig sind. Hier gibt es auch aus Maven heraus keine richtig gute Lösung. Bewährt hat sich, dass grad für besonders auf Abhängigkeiten angewiesene Module (bspw. .ear / .war - Dateien) jeweils ein zugehöriges "modulx-deps" Modul anzulegen, welches einzig und allein den Zweck hat, die entsprechenden Abhängigkeiten bereitzustellen. Das löst jetzt nicht direkt das Problem des statischen Eclipse Mappings, aber vereinfacht die Administration von Abhängigkeiten deutlich. Um in den pom.xml Dateien konfigurierte Dinge direkt zur Laufzeit in die IDE zu bringen, eignen sich einige zusätzliche Helferchen. Mehr dazu im nächsten Abschnitt. Zweiter wichtiger Punkt ist das Thema Repository. Wie bereits erwähnt kann Maven sich alle konfigurierten Abhängigkeiten direkt aus dem Netz vom zentralen Maven Repository herunterladen. Neben den berühmten "central" Repositories (repo1 und repo2.maven.org) gibt es noch eine nahezu unzählige Menge weiterer Verzeichnisse im Netz. Neben Java.net und Codehaus.org gibt es auch zumeist spezielle Snapshot-Repositories verschiedenster Anbieter. Hier ist es nicht ganz trivial, eine geeignete Auswahl zu treffen. Die Konfiguration der notwendigen Repositories kann man sowohl in der pom.xml des Moduls als auch in der globalen settings.xml vornehmen. Hier ist es naheliegend, dass beides nicht wirklich tragfähig ist. Die settings.xml steht zumeist nicht unter Versionskontrolle eines einzelnen Projektes und die Einführung eines speziellen Repositories in einer speziellen pom.xml ist wiederum nicht administrierbar in größeren Teams. Daher sollte man sich schnell überlegen, ob und in welcher Form man ein eigenes Repository für ein Projektteam oder gar die ganze Firma aufbaut. Unter dem Stichwort "Maven Proxy" oder "Repository Manager" wird man schnell im Internet fündig. Neben der schlankeren Variante von Codehaus (maven-proxy) gibt es auch deutlich komfortablere Produkte, wie beispielsweise den Nexus Repository Manager. Ist eine Alternative gewählt, kann man pro Entwickler in der settings.xml direkt ein verbindliches, zentrales Repository angeben. Dies geschieht im Abschnitt <mirrors>. Hier wird einfach mit einem Vierzeiler der zentrale, firmeneigene Spiegel eingerichtet:
 <mirror>
      <id>firmen-repository</id>
      <name>Unser zentraler Maven Proxy</name>
      <url>http://host.firma.de:8080/repository</url>
      <mirrorOf>*</mirrorOf>
 </mirror>
 
Enthält der Tag <mirrorOf> den Wert "*" wird dieser für alle Anfragen zu allen Bibliotheken kontaktiert. Dies kann man bei Bedarf auch weiter einschränken. Beispielsweise nur auf ein spezielles Repository. In komplexen und großen Projekten kann es sich auch lohnen, die Maven Proxys nach Verwendungszweck entsprechend zu teilen. Damit kann man ein Repository für "Snapshots", ein weiteres für "firmeninterne Bibliotheken" und ein weiteres für den Rest der Opensource Bibliothekswelt aufbauen. Dies führt zu einer wesentlich übersichtlicheren Struktur und zu einer deutlich einfacheren zentralen Administration. Einen weiteren Vorteil hat der Einsatz eines eigenen Repositories darüberhinaus noch. Die Verwendung von sogenannten Snapshot-Versionen kann deutlich besser kontrolliert werden. Die meisten Opensource Projekte unterscheiden zwischen den sogenannten Stable oder auch Release Versionen und den Nightly Builds bzw. den Snapshot Versionen. Die Verwendung von letzteren ist eigentlich in Summe zu vermeiden. Leider klappt das nicht immer, da bestimmte Fehler mittelfristig nur in den Snapshots behoben werden und erst Wochen oder gar Monate später in ein neues Release einfließen. Ein Softwareprojekt mit einer Snapshot Abhängigkeit ist allerdings blanker Selbstmord, da keinerlei Qualitäts- bzw. Funktionalitätszusagen für solche Versionen zu erwarten sind. Mit einem eigenen Verzeichnisdienst kann man eine ausgewählte und zumindest teilweise überprüfte Version eines Snapshots durchaus kurzfristig in ein Projekt integrieren. Auch das Thema Softwarequalität kommt bei Maven Projekten nicht zu kurz. Neben dem Checkstyle Plugin ist auch das PMD Plugin Bestandteil der eigentlichen Maven Distribution. Darüber hinaus gibt es noch weitere nützliche Erweiterungen von anderen Opensource Projekten. Findbugs sei hier nur als ein weiteres genannt. Grundsätzlich können diese Plugins an zwei verschiedenen Stellen in den pom.xml Dateien eingetragen werden. Einmal als Prüfung während des Build Prozesses. Dann findet man sie zwischen den Tags <build>[…] </build> oder aber auch als Reporting Plugins. Dann stehen sie zwischen den Tags <reporting>[…] </reporting>. Während die Plugins zwischen den <build>-Tags den eigentlichen Build des Projektes überwachen, sind die Plugins zwischen den <reporting>-Tags für die Informationen auf den Projekt-Report-Seiten zuständig. Nahezu alle Plugins lassen sich mit einer eigenen Konfiguration versorgen. Man kann also pro Projekt entscheiden, welche Metriken man prüfen möchte. Beide Arten sollten nur in der obersten pom.xml Datei im Projekt stehen. Damit lassen sich diese Vorgaben zentral ein oder ausschalten. Wenn die Konfiguration nicht nur beim Build verwendet werden soll, sondern auch den Entwicklern in der IDE zur Verfügung stehen soll, dann muss man noch am Eclipse Plugin eine Konfiguration vornehmen:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<additionalConfig>
<file>
<name>.checkstyle</name>
<url>http://some.place.org/path/to/file</url>
</file>
</additionalConfig>
</configuration>
</plugin>
Letztes Problem bleibt der Umstieg der Entwickler von Ant auf Maven. Die vorhandene, jahrelange Erfahrung macht einen Umstieg auf ein neues System nicht immer einfach. Vor allem dann nicht, wenn es auf den ersten Blick ähnlich aussieht und sich dennoch komplett anders verhält. Es bleibt also der letzte Ratschlag, jemanden im Team zu benennen, der sich einarbeitet und zuständig fühlt für Probleme rund um Build und Packaging. Im einfachsten Fall sind die Basics schnell verstanden und gelernt. In Spezialfälle muss man sich einarbeiten. Eine Lösung gibt es immer.

Plugins und Helferchen

Wenn im Apache-Maven-Land keine Lösung in Sicht ist, dann kann man sich noch auf die Suche nach Lösungen außerhalb begeben. Dringendste Empfehlung für Eclipse Benutzer ist es, die m2eclipse Integration von Codehaus zu installieren. Mit ihr werden die in den pom.xml definierten Abhängigkeiten direkt in der IDE aufgelöst. D.h. man spart sich das lästige eclipse:eclipse Kommando und bekommt auch keine Probleme mehr mit geänderten Definitionen. Darüber hinaus kann man noch eine Vielzahl weiterer nützlicher Funktionen nutzen. Neben dem grafischen Editor für die pom.xml Dateien, gibt es eine grafische Übersicht über die Abhängigkeiten und vieles mehr. Ebenfalls nützlich ist das Maven Plugin taglist von Codehaus. Einmal in die Konfiguration eingebunden, durchsucht es die Sourcen nach beliebigen Tags und generiert einen Report darüber. Hier findet man dann beispielsweise alle Stellen in den Quellen, die mit "TODO", "FIXME" oder selbstdefinierten Tags markiert sind. Das ist ein sehr hilfreiches Werkzeug für Entwickler. Wem das noch nicht genug ist, der kann sich auf die Suche nach weiteren Plugins begeben. Neben der Liste der offiziellen Plugins auf der Projekthomepage finden sich bei Codehaus und auch bei Google Code nahezu unzählige weitere Plugins.

Fazit

Auch wenn der Einstieg in Maven gewöhnungsbedürftig ist und es einem doch hin und wieder mal so vor kommt, als würde das Werkzeug sprichwörtlich machen, was es will, so ist es doch mehr als einen Blick wert. Grade in großen Teams kann es seine Mehrwerte ausspielen. Ein über das gesamte Unternehmen hinweg standardisierter Build-Prozess vereinfacht nicht nur das technische Miteinander, sondern motiviert auch dazu den Gedanken an wiederverwendbare Module deutlich ernster zu nehmen. So richtig spannend wird es, wenn man den Gedanken mit einem unternehmenseigenen Repository weiterverfolgt. Hier kann man nicht nur sehr gut steuern, welche Opensource Projekte verfügbar sind und eingesetzt werden dürfen. Es besteht sogar die Möglichkeit dies unter Berücksichtigung von relevanten Lizenzen zu tun. Damit lässt sich wesentlich leichter Einfluss darauf nehmen, welche Bibliotheken in welchen Projekten verwendet werden. Größtes Problem bleibt die recht komplexe Konfiguration aller Elemente in einem Projekt. Grad ein vollständiges und umfassendes Zusammenspiel von Build bis hin zur Entwicklungsumgebung setzt ein paar Stunden Konfigurationsarbeit voraus. Ist dies allerdings erledigt, dann spielt ein stabiler Build seine ganzen Stärken täglich erneut aus. Einfachster Weg, um diese Hürde in Projekten zu nehmen ist es, wenn ein entsprechend qualifizierter Spezialist die Initialen Arbeiten übernimmt und ein Verantwortlicher im Projekt die laufenden Tätigkeiten verfolgt. Wer jetzt allerdings darüber nachdenkt, alle alten Ant-Skripte wegzuschmeißen und komplett auf Maven zu migrieren, der sei gewarnt. Ant ist nicht Maven und ein solcher Versuch ist durchaus Zeitaufwändig. Darüber hinaus gibt es Konstellationen, welche sich mit Maven einfach nicht abbilden lassen. Vor allem die Einschränkung, dass pro Modul lediglich ein Ergebnistyp (jar, war, et cetera) erstellt werden kann, wird bei der Umstellung von Ant-basierten Projekten häufig ein Problem sein. Zum Glück gibt es sowohl in Ant die Möglichkeit Maven aufzurufen und auch andersherum gibt es die Möglichkeit aus einem Ant Script ein Maven Plugin zu machen.

Links und Literatur