Buildautomation: Maven, Gradle, Ant

  • Am Anfang von jedem neuen Projekt steht der Entwickler vor der Entscheidung, was er für externe Bibliotheken verwenden will und wie die Struktur seines Programmes aussehen soll.
    Dabei gibt es verschiedene Varianten dies umzusetzen. Einige dieser Möglichkeiten möchte ich hier näher erläutern.

    1 Begriffsklärung

    Um zu verstehen, was Maven, Gradle und Ant eigentlich sind, muss man sich mit der Einbettung von externen Bibliotheken beschäftigen. Programm können mithilfe von sogenannten Bibliotheken einfach erweitert werden. Diese stelle neue Funktionen bereit, welche nicht mehr selber geschrieben werden müssen. Dies hat den Vorteil einen übersichtlichen Code zu bewahren. Zudem sind diese Bibliotheken meist sehr ausgereift und daher auch sehr effizient.

    Bibliotheken kann man nun auf verschiedenen Wegen in das eigene Projekt einbinden. Die einfachste ist einfach die Bibliothek als Jar mit zu kompilieren. Dies hat den Nachteil, dass man die Datei downloaden muss und selbständig immer wieder nach Updates dieser schauen muss.

    1.1 Ant mit Ivy

    Ant war eines der ersten "modernen" Buildtools. Die von Apache entwickelte Software setzt auf eine XML Konfiguratrionsstruktur, welche die Bedienung relativ einfach für Neueinsteiger gestaltet. Nachteil des XML's ist, dass es hierarchisch aufgebaut ist und daher nicht unbedingt für Prozeduren geeignet ist. Nachdem das Dependency-Management ein "must to have" wurde, kam noch das Addon Ivy dazu, welche dies unterstützte.


    1.2 Maven

    Maven wurde auf Ant aufgebaut mit dem Versuch, die Probleme vom Vorgänger zu beheben. Dies ist aber nur bedingt durch das Festhalten an der XML Struktur geschehen. XML ist und bleibt einfach eine stark standardisierte Sprache und erlaubt relativ wenig Anpassung. Ein Dependency-Management wir nun direkt von Maven mitgebracht. Durch den Lebenszyklus von Maven kann können mehere Ziele (Goals) definiert werden um unterschiedliche Aufgaben zu erledigen. Einige davon sind die Generierung eines JavaDocs, Codeüberprüfung durch Checkstyle oder Testen mit Unit Tests.


    1.3 Gradle

    Grdle ist der neuste Standard dieser Build-Automation-Tools. Es kombiniert die Effizienz von Ant und die Flexibilität von Maven. Die Vorteile durch das Setzten auf die Sprache Groovy sind hier entscheidend. Gradle kann sehr einfach angepasst werden und verschiedenste Aufgaben erledigen. Aufgaben können in mehrere Abschnitte unterteilt werden, der zu schreibende Code ist kurz gehalten und sehr übersichtlich und es können Aufgaben wie Statische Code Analyse, Testing, Packen von Jars und Deployment übernommen werden. Ein großer Vorteil ist zudem die enorme Geschwindigkeit im Vergleich zu Maven und Ant.


    Hier gibt es nun nochmal eine kleine Animation um die gigantischen Performance Unterschiede zwischen Gradle (links) und Maven (rechts) zu visualisieren:

    gradle-vs-maven.gif

    2 Einbinden von Gradle in ein Projekt

    Gradle ist wie Maven eigentlich nur eine Nebensache des eigentlichen Codes. Es steht unabhängig neben dem eigentlichen Projekt und kann somit einfach auch in existierende Projekte eingebunden werden. Viele IDE's wie IntelliJ, NetBeans und Eclipse stellen schon von Haus aus eine Gradle Integration bereit um direkt loszulegen.


    Die manuelle Installation von Gradle werde ich an dieser Stelle nicht erläutern. Wer dies trotzdem gerne machen möchte, kann auf der offiziellen Webseite von Gradle gerne dies nachlesen.


    In IntelliJ werden wir nun einfach bei der Erstellung eines neuen Projektes Gradle, wie im folgenden Bild zu sehen auswählen. Die nachfolgende Erstellung des Projektes ist darauf hin wie immer.


    Haben wir dieses nun erstellt, wird sich Gradle wie von Zauberhand selber installieren. Selbst muss man eigentlich nicht mehr wirklich viel machen und kann theoretisch sofort mit dem Programmieren loslegen.

    Shell-Script
    1. Download https://services.gradle.org/distributions/gradle-5.2.1-bin.zip (87.43 MB)
    2. Download https://services.gradle.org/distributions/gradle-5.2.1-bin.zip finished succeeded, took 7 s 481 ms
    3. Gradle Daemon started in 601 ms
    4. > Task :wrapper
    5. BUILD SUCCESSFUL in 3s
    6. 1 actionable task: 1 executed
    7. CONFIGURE SUCCESSFUL in 6s


    3 Die build.gradle

    Die build.gralde ist das was bei Maven die pom.xml ist. Sozusagen der Einstieg- und Konfigurationspunkt von Gradle.

    Nach dem Öffnen dieser Datei sehen wir zuerst den Block plugins. Hier werden die zu benutzenden Gralde Plugins angegeben. Dies kann zum Beispiel das Java-Plugin sein, aber auch ein Application Plugin oder ein Shade Plugin. Da ich hier ein Java Projekt habe, wird direkt das Java Plugin vorinstalliert.

    Code
    1. plugins {
    2. id 'java'
    3. }

    Folgend finden wir noch ein paar Konfigurationen, welche die Group und die Version beinhalten.

    Code
    1. group 'tk.enderlein'
    2. version '1.0-SNAPSHOT'
    3. sourceCompatibility = 1.8

    Danach kommt der eigentlich wichtige Teil die Repositories und Dependencies. Dort werden alle gewohnten Bibliotheken eingebunden. Im Vergleich zu Maven hat sich hier die Syntax stark vereinfacht. Wir geben nun nur noch einen String an, der alle Informationen beinhaltet (also die group, artifactId und die Version). Hier wird zum Beispiel schon direkt JUnit mit eingebunden. Der Begriff testCompile steht für den Fall, indem diese Dependency eingebunden werden soll. Im Falle eines Unit Testes wird also JUnit mit eingebunden.

    Code
    1. repositories {
    2. mavenCentral()
    3. }
    4. dependencies {
    5. testCompile group: 'junit', name: 'junit', version: '4.12'
    6. implementation 'com.google.code.findbugs:findbugs:3.0.1'
    7. }

    Zudem habe ich wie zu sehen noch die FindBugs Bibliothek von Google eingebunden. Dies geht einfach mit dem Begriff implementation, wenn die Bibliothek im nachhinein schon vorausgesetzt wird, oder compile, wenn die Bibliothek mit in die fertige Jar eingebunden werden soll (also mit kompiliert werden soll).


    Um nun eine Ausführbare Datei mit allen Dependencies zu bekommen, schreiben wir uns einen kleinen Task der das alles für uns erledigt. Hier wird zudem noch der Name der Jar umgeschrieben und alle Datein die eingebunden wurden mit verpackt. Mit with jar verweisen wir auf den default Task, der sonst die Jars zusammenpackt.

    Code
    1. task fatJar(type: Jar) {
    2. baseName = project.name
    3. from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    4. with jar
    5. }

    Diesen können wir dann einfach durch die sich selbst erstellende Startkonfiguration in IntelliJ ausführen und erhalten im Ordner build/libs/ unsere fertige Jar.

    Alternativ können wir auch einfach den Consolen-Befehl gradle fatJar ausführen.

    4 Warum sollte man jetzt Gradle bevorzugen?

    Gradle ist wie schon erwähnt einfach die schnellere und flexiblere Lösung. Es ist einfach erweiterbar und bieten um einiges mehr Funktionen als Maven und Ant.

    Wenn ihr Gradle noch nicht benutzt habt, dann probiert es doch einfach mal aus!


    Wenn mehr Interesse an Gradle besteht, kann hier noch der Wissensbedarf gefüllt werden.

Teilen