Die ominöse pom.xml
Im letzten Post haben wir gesehen, dass eine minimale pom.xml genügt, um Maven zum Kompilieren eines Standard-Projekts zu bewegen. Allerdings kann dieses Projekt nicht wirklich viel. Insbesondere kann es keine Abhängigkeiten auflösen.
Und damit kommen wir zur Maven-Magie. Wenn unser Projekt von einer Library A abhängig ist, die wiederum von den Libraries B, C und D abhängig ist, und diese wieder von Noch weiteren Libraries, undsoweiter, dann ist das ziemlich mühsam. Meistens merkt man ja erst beim Debuggen des fertigen Programms, dass irgendein .jar fehlt und muss das mühsam suchen und installieren. Nur um dann herauszufinden, dass dieses Jar dann wieder ein anderes braucht, das wir ebenfalls noch nicht haben.
Bei Maven genügt es, die Abhängigkeit zu A zu deklarieren, und es holt dann selber alle Abhängigkeiten dazu. Damit erkärt sich auch, wieso Maven beim ersten Start erstmal das halbe Internet herunterlädt. Viele Projekte verwenden irgendwelche Apache-Libraries, und sei es nur Log4j oder commons-io. Und Apache Libraries sind berüchtigt dafür, dass sie weit miteinander verknüpft sind. EIne Apache Library zu verwenden bedeutet so über den Daumen gepeilt, , dass man zehn Libraries installieren muss.
Mit Maven ist das alles egal. Man deklariert die, die man selber braucht und Maven erledigt den Rest.
Und das macht man so:
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.36</version>
</dependency>
</dependencies>
Die einzelnen Elemente habe ich ja schon im letzten Post erklärt. Eine gute IDE wie Idea lädt die Library herunter, sobald man die “dependency” einträgt, und man kann sie sofort im Projekt verwenden.
Und woher weiss man die genauen Angaben zu einer Library?
Zum Beispiel, indem man zu Maven central geht und dort ins Suchfeld das einträgt, was man zu der gewünschten Library weiss. In unserem Fall zum Beispiel “mysql-connector”. Die Seite spuckt dann eine Liste mit allen Treffern aus, und wenn man auf die gewünschte Versionsbezeichnung, hier also ‘5.1.36’ klickt, dann kommt man zu einer Detail-Seite, in der man links unter “dependency information” die Angaben für pom.xml gleich fixfertig für copy&paste vorbereitet findet. Nicht wirklich schwierig, nicht wahr?
Woher und wohin?
Bevor ich weitere Bereiche der pom.xml betrachte erst mal ein kleiner Einschub: Woher holt maven die libraries? Und wohin gehen sie? Im Projektverzeichnis sind sie jedenfalls nicht.
Wie immer gilt hier “convention over configuration”: Es gibt Standards, die man ändern kann. Standardmässig sucht Maven Libraries in maven central und kopiert
sie ins “local repository” (Aha! Das ist dieses ominöse Repository, dem wir schon bei mvn install
begegnet sind). Dieses Repository befindet sich
auf linux und Mac Rechnern standardmässig in ~/.m2
, in anderen Betriebssystemen vermutlich irgendwo anders. Darin befindet sich ein weiterer Ordner
mit dem überaus passenden Namen repository
. Und darin befinden sich sämtliche Artefakte, die heruntergeladen oder lokal installiert wurden.
Ach ja: Mit “Artefakte” ist im Apache-Speak alles gmeint, was von einem Progamm erstellt wurde. Also vor allem Jars und andere Compilate. Wieso ein Quellcode-File kein “Artefakt” sein soll (es ist ja auch nicht auf Bäumen gewachsen, sondern wurde künstlich ertsellt), ist ein Geheimnis der Apachen, auf das man nicht unbedingt näher einzugehen braucht.
Wie auch immer. Die Struktur innerhalb des Repository ist:
[groupId]
[artifactId]
[version]
(Dateien)
Wobei groupId hierarchisch geteilt sein kann. Also ch.rgw.webelexis würde so aussehen:
[ch]
[rgw]
[webelexis]
[1.0.0]
Die Dateien im Versions-Verzeichnis sind mindestens ein <artifactId>-<version>.jar, und eine Datei namens <artifactId>-<version>.pom, welche sich als Kopie der pom.xml entpuppt. Dazu möglicherweise Prüfsummendateien etc.
Maven kopiert bzw, erstellt also alles im local repository, und die Abhängigkeiten im Projekt werden zu diesem local repository erstellt. Es ist daher nicht notwendig, die jars in jedes Projekt zu kopieren, das sie benötigt. Wie man ein Projekt so “deployt”, dass man es mitsamt allen Abhängigkeiten weitergeben kann, zeige ich später.
Wenn man gerade kein Internet hat, dann kann man maven anweisen, offline zu arbeiten, also nur mit diesem local repository.
mvn -o package
erstellt ein Package, ohne erst im Internet nachzusehen, ob es irgendeas upzudaten gibt. Das wird natürlich nur dann klappen, wenn alle benötigten Abhängigkeiten schon lokal vorhanden sind.