Apache Maven #

Maven ist ein Tool, um Java-Projekte zu bauen und zu verwalten. Es hat einiges mit ApacheAnt gemeinsam, geht aber darüber hinaus und hat einen ganz anderen Ansatz. Ich habe mich entschlossen, mich mal mit Maven zu beschäftigen und möchte hier Informationen für andere und für später sammeln.

Abgrenzung zu anderen Tools #

Bei Maven beschreibt man einige (wenige) grundlegende Dinge über sein Projekt. Im einfachsten Fall ist das nur der Namen und die Version. Dann werden über Befehle ähnlich wie bei Ant sogenannte "goals" oder "phases" ausgelöst, die dann das Projekt bauen. Die Phasen entsprechen dabei Vorgängen wie "Compilieren", "Unit-Tests ausführen", "als JAR verpacken" etc. Man schreibt allerdings nicht prozedural auf, welche Befehle man ausführen will (wie bei ApacheAnt), sondern überlässt das recht komfortablen, konfigurierbaren Plugins.

Maven baut stark auf Konventionen auf, d.h. es gibt einmal festgelegte Plätze, wo z.B. der Quelltext sich befindet, wo die Klassen hinsollen etc. Alle diese Einstellungen werden dann von allen Plugins automatisch respektiert, ohne daß man dies in jedem Task bei jedem Befehl wieder neu angeben müsste.

Die zwei Haupt-Verbesserungen zu Ant sind, daß man einerseits eine Paketverwaltung für Bibliotheks-Abhängigkeiten bekommt und andererseits, daß es bereits eine große Menge von komfortablen Plugins gibt, die meistensteils direkt "out of the box" funktionieren. Man mag meinen, daß es auch sehr viele Ant-Tasks zu allen möglcihen Zwecken gibt, aber es ist dennoch ein Unterschied, einen Befehl zu bekommen, dessen Parameter man erst verstehen und heraussuchen muss oder ein Plugin, das meistens von ganz alleine funktioniert.

Der Haupt-Nachteil ist, daß man letztlich nicht mehr selber Tasks "programmieren" kann, wie das unter Ant eigentlich selbstverständlich war. Obwohl ich das immer stark ausgenutzt habe, bin ich bisher noch nicht an den Punkt gekommen, wo mich Maven behindert. Ich bin aber noch nicht fertig... ;-) Natürlich bleibt einem die Möglichkeit, auch eigene Plugins zu schreiben. Diese sind dann aber vollständige Java-Klassen und nicht bloss ein paar Zeilen in der "build.xml" wie bei Ant.

Eine bessere Vorstellung habe ich bekommen, als ich das Zusammenspiel mit IDEs besser verstanden habe. Ein Maven-POM (also die Projekt-Konfigurationsdatei) kann man direkt in eine Eclipse-Projektkonfiguration übersetzen. Im Grunde genommen sollte dieser "POM-Standard" (irgendwann) als Konfigurationsdatei in allen IDEs deren eigenen Konfigurationsdateien ersetzen und damit vereinheitlichen können. Natürlich wird immer noch jede IDE irgendwas anders machen, einen anderen Compiler benutzen, bessere Auswertungen anzeigen können oder sonstwas - genauso ist es mit den verschiedenen Maven-Plugins. Man muss diese wie Module einer IDE sehen, die mit den gemeinsamen POM-Daten arbeiten.

Ein herausragender Nachteil von Ant ist, daß es durch die "XML-Programmierung" sehr statisch und unflexibel ist. Das ist bei Maven noch viel stärker, weil man ja eben gar nicht mehr programmieren kann (oder man schreibt eigene Plugins - Ich will hier aber auch nicht verschweigen, daß es ein Plugin zur Ausführung von Ant-Tasks gibt...). Komischerweise fällt das bei Maven gar nicht so auf, weil viele der vorher zu programmierenden Probleme mit den vorhandenen Plugins schon ganz gut gelöst worden sind.

Eine andere und modernere Alternative ist Gradle. Es baut auf Groovy auf und bietet die von Groovy als Skriptsprache gewohnte riesige Flexibilität bei der gleichzeitigen Übernahme einiger sinnvoller Konzepte von Maven. Zum Vergleich mit Maven kann man z.B. sehen, warum Hibernate sich für Gradle entschieden hat: http://community.jboss.org/wiki/Gradlewhy und http://community.jboss.org/wiki/MavenProblems

Die Webseite des Projektes findet sich unter http://maven.apache.org. Dort findet sich eine gute Kurzeinführung in die Maven-Konzepte und weitere Doku. Leider ist diese Dokumentation, wenn man über die Schnelleinführung hinausgeht, ziemlich grottenschlecht. Irgendwie muss man meist sehr viel Ahnung von dem Problem haben, das ein Plugin löst, um dessen Doku zu verstehen. Wenn man aber gerade durch die Plugins stöbert, um auf neue Ideen zu kommen, hilft das nix.

Vor der kompletten Verzweiflung und Hinwendung zu einem anderen Build-Tool habe ich dann aber per Google herausgefunden, daß man das exzellente Buch Maven: The Definitive Guide auch frei herunterladen kann. Es steht auf der Webseite der Firma Sonatype, die u.a. auch das Eclipse-Plugin m2eclipse geschrieben hat: http://www.sonatype.com/products/maven/documentation/book-defguide. Dieses Buch empfehle ich uneingeschränkt jedem, der sich ernsthaft mit Maven beschäftigen möchte.

Wer Bibliotheken sucht, die er über das Paketmanagement laden kann, wird auch http://mvnrepository.com/ und seine Suchfunktion gerne nutzen.

Wer es gerne von einem echten Menschen erfährt, anstatt sich durch das Netz zulesen, findet einen guten Einführungs-Vortrag als Videostream auf deutsch auf http://www.jughh.org/display/jughh/Maven+2 .

Erste Schritte #

In der Dokumentations-Übersicht finden sich zwei Guides "Maven in 5 Minutes" und "Maven in 30 Minutes". Diese sind ein guter Anfang, um mal reinzuschauen. Nach Lesen dieser Dokumente kam ich mir allerdings etwas alleingelassen vor. Jetzt sollte man "The Definitive Guide" lesen und vielleicht ein paar meiner Bemerkungen als Hilfestellung nehmen.

Tips und Bemerkungen #

Archetypen #

Am Anfang habe ich nicht richtig begriffen, was es mit diesen Archetypen auf sich hat. Das sind einfach Templates, d.h. leere Projekte, die als neues Projekt kopiert werden können. Ist das Projektverzeichnis damit einmal erstellt, hat der ursprüngliche Archetyp keine weitere Bedeutung mehr. Wer keinen Archetyp-Namen angibt, bekommt den "Standard"-Archetyp, der IMHO erstmal am besten ist. Nun gibt es Leute, die z.B. zum Programmieren von Swing-Applikationen ein Gerüst geschrieben haben, damit man schonmal eine Klasse hat, die ein Fenster öffnet. Ich persönlich schreibe meine Klassen ja lieber selber, aber wer es mag, kann sich ja mit den Archetypen beschäftigen.

Abhängigkeiten #

Die Doku auf der Webseite tut immer so, als wüsste man von ganz alleine, welche Bibliothek in welcher Version man einbinden will. Um hier Hilfe zu bekommen, kann man entweder das Zentral-Repository per Browser durchsuchen oder auf http://mvnrepository.com/ gehen, wo es eine gute Weboberfläche zur Suche gibt, in der dann auch die Projektbeschreibung ausgegeben wird etc. Das erreicht zwar nicht die Qualität vom CPAN für PerlProgrammierung, ist aber ein Anfang.

Eclipse-Integration #

Die Eclipse-Integration m2eclipse sollte man auf jeden Fall installieren. Die Konfiguration des Projektes geschieht dann im Grunde nur noch über den POM-Editor, aus dem heraus dann automatisch die Eclipse-Einstellungen generiert werden.

Help-Plugin #

Mit

  mvn help:describe -Dfull -Dplugin=exec

Gibt es eine Hilfe z.B. zum "exec"-Plugin. Dort werden alle Goals (also alle Befehle) sowie deren Parameter aufgeführt.

mehrere Source-Verzeichnisse #

Manchmal hat man seine Sourcen in verschiedene Verzeichnisse aufgeteilt. Ich benutze das z.B. für automatisch generierte Source-Files. Mit dem build-helper-Plugin kann man das auch einstellen. Ein Beispiel gibt es hier: http://mojo.codehaus.org/build-helper-maven-plugin/usage.html .

Hübscherweise funktioniert das so übrigens auch mit m2eclipse, d.h. man erhält in Eclipse auch ein zusätzliches Source-Verzeichnis. Sehr schöne Integration! :-)

Übrigens ist diese Art der Notation meiner Meinung nach völlig am Thema vorbei. Statt in der build-Konfiguration anzugeben, wo meine Sourcen liegen, aktiviere ich ein Plugin und sage diesem, daß es in einer bestimmten Phase ein angegebenes Source-Verzeichnis hinzufügt. Das ist nicht "mein Projekt beschreibend", sondern das ist prozedural programmiert. So hätte man das auch ohne Maven haben können...

JARs verwenden, die nicht im Repository sind #

Generell sollten alle Bibliotheken, von denen mein Projekt abhängig ist, versioniert aus dem zentralen Repository kommen. Dafür gibt es Gründe, die auch relativ einleuchtend sind. Was mache ich aber nun, wenn eine von mir verwendete Bibliothek dort nicht vorhanden ist? Interessanterweise habe ich noch keinen ordentlichen Weg gefunden, Bibliotheken mit Maven einzubinden, die ganz klassisch im "lib"-Verzeichnis stehen. (Ich vermute mal, daß ich den Wald vor lauter Bäumen nicht sehe und mir bald jemand hier erklären wird, welches Plugin man dafür benutzt...)

Man kann jedoch ein einfaches JAR-File ohne weiteres in sein lokales Repository kopieren und dort dann benutzen wie andere Artefakte auch. Wie das geht, ist auf http://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html beschrieben. Ich habe z.B. folgenden Befehl für die Bibliothek "jsane-base" benutzt:

  mvn install:install-file -Dfile=JaBaDA/lib/JSane-Base-0.8.jar -DgroupId=de.bayen -DartifactId=jsane-base -Dversion=0.8.0 -Dpackaging=jar

Nun gibt es manchmal (nun gut - eigentlich immer) auch wieder Abhängigkeiten dieser eben installierten Bibliotheken. Hierzu kann man die automatisch erzeugte POM-Datei ändern bzw. eine neue anlegen. Dort kann man dann weitere Abhängigkeiten eintragen wie in normalen POMs auch. Diese Datei kann dann z.B. so aussehen.

  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>de.bayen</groupId>
  <artifactId>jsane-gui</artifactId>
  <name>jsane-gui</name>
  <description>jsane-gui</description>
  <version>0.8.0</version>
  <dependencies>
        <dependency>
                <groupId>de.bayen</groupId>
                <artifactId>jsane-net</artifactId>
                <version>0.8.0</version>
        </dependency>
        <dependency>
                <groupId>de.bayen</groupId>
                <artifactId>jsane-base</artifactId>
                <version>0.8.0</version>
        </dependency>
  </dependencies>

-- ThomasBayen


Tags:  Java

Add new attachment

Only authorized users are allowed to upload new attachments.
« This page (revision-11) was last changed on 08-Apr-2011 11:56 by ThomasBayen