Mit Maven raus aus der Abhängigkeit

Hallo Spaß-Coder.

Abhängigkeiten sind nicht schön. Wir versuchen diese in unseren Code so weit es geht zu vermeiden (siehe etwa unsere Artikelserie zum Thema SOLID). Auf der anderen Seite freuen wir uns, wenn wir das Rad nicht neu erfinden müssen. Gerade im Umfeld von Java sind leistungsstarke, meist kostenfreie Open-Source-Lösungen vorhanden, die wir nutzen können, ohne selbst das detaillierte Know-How haben zu müssen oder für die Qualitätssicherung zu sorgen.

Aber wie behalten wir den Überblick über diese ganzen tollen Bibliotheken? Wie stellen wir sicher, dass wir diese auch an unsere Kunden liefern? Helfen kann uns dabei Apache Maven.

In dieser Artikelreihe möchten wir ein bisschen Licht ins Dunkel um das Mysterium von Apache Maven bringen. Fragen wie „Was ist Maven?“, „Wobei hilft mir Maven?“ oder „Wann soll ich Maven verwenden?“ werden wir beantworten. Dabei starten wir ganz am Anfang und versuchen die Einstiegshürde so klein wie möglich zu halten. Wer jetzt noch ängstlichen Respekt vor Maven hat, sollte die Angst nach dieser Artikelreihe abgelegt haben und nur noch anerkennenden Respekt für Maven empfingen.
Unserer Ansicht nach ist Maven im Umfeld der Java-Programmierung ein unverzichtbar hilfreiches Werkzeug.

Um euch nicht mit grauer Theorie und Absichtserklärungen zu langweilen, halten wir den Teil darüber, was Maven ist oder welche Ziele es verfolgt kurz und knapp und stürzen uns gleich ins Eingemachte.

 

Was ist Maven?

  • Werkzeug zum Management von Software Projekten, typischerweise Java-Projekte.
  • Verwaltung von Build, Auswertungen (statische Code-Analyse) und Dokumentationen (Hauptsächlich JavaDoc).
  • Unterstützt die zentralisierte Verwaltung von Software Projekten. Unterstützt also die Zusammenarbeit im Team.
  • Maven ist kein reines Build-Werkzeug. Es unterstützt vielmehr den gesamten Application Lifeycle (ALM).

Was hinter dem letzten Punkt steckt werden wir in dieser Artikelserie mit und mit aufdecken.

 

Ziele von Maven

  • Vereinfachung des Build Prozesses
  • einheitliches Buildsystem
  • Qualitativ hochwertige Projekt-Informationen
  • Guidelines für best-practice Entwicklung

Weitere Informationen dazu, was Maven ist oder welche Ziele es verfolgt, kann auf der Webseite von Apache Maven (in englischer Sprache) gefunden werden. Für uns soll das aber erstmal reichen.

 

Terminologie

Maven verwendet ein paar Begriffe, die immer wiederkehren und die man kennen und zuordnen können sollte. Hier die wichtigsten, wie für das Verständnis dieses und der weiteren Artikel notwendig sind.

  • Modul
    • Ein durch Maven verwaltetes Software Projekt.
  • Build
    • Durchlaufen eines in Phasen aufgeteilten linearen Zyklus mit dem Ziel, ein definiertes Artefakt zu erzeugen.
  • Artefakt
    • Ein durch den Build erzeugtes Produkt oder Ausgabe, z.B. JARs, WARs
  • Deployment
    • Das Veröffentlichen eines Artefakts zur weiteren Verwendung

 

Project Object Model

Ein weiterer Begriff aus dem Umfeld von Maven ist die POM. Die POM – oder mit vollem Namen das Project Object Model – ist die zentrale stelle, an der ein Maven-Modul konfiguriert wird. Pro Modul gibt es genau eine Datei mit Namen pom.xml (das ist die POM), in der alles konfiguriert wird, was für das Modul erforderlich ist.

Die POM dient …

  • … der Konfiguration des Build-Zyklus
  • … der Beschreibung des erzeugten Artefakts zum Konsumieren durch andere, darauf aufbauende Module

Dabei wird nicht beschrieben wie der Build zu erfolgen hat – stattdessen wird beschrieben was herauskommen soll.

 

Ein Beispiel

Die POM

Diese XML-Datei beschreibt ein Modul vollständig. Gehen wir die einzelnen Abschnitte einmal durch.

  • <?xml …>
    • die pom.xml ist reines XML und wird auch so konfiguriert.
  • <project …>
    • dies ist der Haupt-Tag. Hierin befinden sich die Konfigurationen für das Modul. Die Namespaces helfen bei der Bearbeitung, etwa in einer IDE.
  • <modelVersion>
    • Das ist die Version der Konfiguration. Diese ändert sich sehr selten.
    • Sollte im Moment immer 4.0.0 sein.
  • <groupId> / <artifactId> / <version>
    • Hierüber wird unser Modul eindeutig identifiziert.
    • Die Gruppe muss eindeutig sein. Hier hat sich die Rückwärtsschreibweise von Domänen etabliert, wie in de.invidit. Damit ist sichergestellt, dass sie eindeutig ist.
    • Das Artefakt trägt den Namen unseres Moduls. Wir haben hier also ein Modul, dass tictactoe heißt. Innerhalb einer Gruppe muss der Name des Artefakts eindeutig sein.
    • Die Version zu guter Letzt bestimmt nun ganz genau, welche in welcher Version unser Artefakt vorliegt.
    • Diese drei Werte werden auch GAV genannt. Die Abkürzung ergibt sich aus den Anfangsbuchstaben.

Damit haben wir unser Maven-Modul beschrieben. Es hat einen Namen, gehört zu einer Gruppe und hat eine eindeutige Versionsnummer. Eine Besonderheit hier ist die Angabe -SNAPSHOT hinter der Version. Diese sagt aus, dass es sich um ein Modul handelt, welches sich noch in der Entwicklung befindet. SNAPSHOT-Abhängigkeiten sollten nicht in produktiven Umgebungen verwendet werden, da diese nicht eindeutig wiederherstellbar sind.

Erst nach der Freigabe der Software wird die SNAPSHOT-Version entfernt. Eine Release-Version erkennt man also ganz einfach daran, dass in der Versionsangabe kein SNAPSHOT vorkommt (in unserem Beispiel wäre also 0.0.1 die Release-Version).

 

Der Code

Schauen wir mal in die Main-Methode von tictactoe, hier gibt es eine Stelle, die wir gerne verbessern möchten.

In der markierten Zeile würden wir gerne das fiese printStackTrace() durch eine ordentliche Log-Ausgabe ersetzen. Zum Glück wissen wir, dass es mit Log4J eine stabile und gut funktionierende Open-Source-Lösung für unser Problem gibt. Diese wollen wir nun verwenden.

Unser neuer Code sieht also anschließend so aus:

Was aber müssen wir alles tun, damit diese Zeile auch funktioniert?

  1. Wir müssen die Klassenvariable logger definieren
  2. Wir müssen das package in einer import-Anweisung angeben, in dem die Klasse definiert ist
  3. Wir müssen die Klasse im Classpath verfügbar machen

 

Probleme? Nicht für mich!

Dazu brauchen wir aber kein Werkzeug, oder? Das ist doch super einfach. Drei Zeilen Code einfügen, die JAR herunterladen und in der IDE in den Classpath packen, fertig! Wozu Maven und diese pom.xml?

Spannend wird Maven dann, wenn man nicht alleine an einem Projekt arbeitet, sondern im Team. Ich habe natürlich keine Probleme mit der Änderung, ich habe ja alles gemacht. Checke ich den Code aber nun in unser SVN ein und jemand aus dem Team checkt es aus, bekommt dieser einen Compilefehler. Er hat ja die neue Bibliothekt, also Log4J, noch gar nicht. Er muss sie also ebenfalls herunterladen und in seiner IDE dem Classpath hinzufügen.

Aber woher bekommen die anderen Teammitglieder die Klasse? Woher wissen sie, in welcher Version die Klasse verwendet wird? Wie stellen wir sicher, dass die Klasse nicht bereits in einer anderen Version verwendet wird? Diesen Fragen beantwortet Maven für uns!

Statt die JAR-Datei manuell im Internet zu suchen, herunterzuladen und in den Classpath einzufügen, brauchen wir Maven nur mitzuteilen, was wir brauchen.

Wir ergänzen also die Abhängigkeit (engl. dependency) in der pom.xml. Dabei geben wir im neuen Bereich <dependencies> eine neue <dependency> an und verwenden dafür die GAV von Log4J.

Maven kümmert sich nun darum, dass die passende JAR-Datei heruntergeladen wird und stellt sie unserem Modul im Classpath zur Verfügung. Bauen wir eine größere Anwendung und packen diese in ein WAR, sorgt Maven auch dafür, dass alle Abhängigkeiten mit eingepackt werden.

Die Mitglieder aus unserem Team checken nun einfach das Projekt aus und Maven versorgt sie mit den passenden Abhängigkeiten. Einfach, oder?

 

Zusammenfassung

Durch die einfache Definition unseres Moduls in einer XML-Datei bilden wir die Basis für ein Maven-Projekt. Hier können wir dann unsere Abhängigkeiten komfortabel verwalten und dem Team automatisch zur Verfügung stellen.

In Maven steckt noch viel mehr. Auch hier sind wir erst an der Oberfläche geblieben. Im nächsten Artikel wollen wir uns das Ganze mal in der Praxis anschauen und sehen, wie wir Maven dann auch tatsächlich benutzen und was „unter der Haube“ dabei so alles passiert.

 

Viel Spaß beim Verwalten der Abhängigkeiten.

Eure Spaß-Coder

 

Dieser Artikel basiert neben unseren Erfahrungen auf den Ausführungen aus:

  • Maven-Training von René Gielen – IT Neering (nahezu alles, was wir über Maven wissen, wissen wir direkt oder indirekt von ihm. Danke René!)
  • http://maven.apache.org/
  • Hüttermann, Michael – Agile ALM, Manning Publications Co., 2011

3 Kommentare

  1. Bisher haben wir uns mit Gradle noch nicht auseinandergesetzt. Aber danke, dass du uns darauf aufmerksam machst.
    Das Problem bei neuen Tools dieser Größenordnung ist in aller Regel die Umstellung des vorhandenen Systems auf das neue Tool.

    Sicherlich spricht nichts dagegen, es mal für ein kleines Projekt auszuprobieren. Ich schreibe es mir auf jeden Fall mal auf meine (ohnehin schon viel zu lange) „Wenn mal wieder Zeit ist“ Liste 😉

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.