Hallo,
die Bezeichnungen hören sich schon sehr gut an…aber warum dann die ParentPom in ein paralleles Verzeichnis gepackt wird ist mir nicht klar…
Also einfach:
pom.xml (parent)
+--- Grundprojekt (pom.xml)
+--- Projekt2 (pom.xml)
+--- Projekt3 (pom.xml)
+--- Projekt4 (pom.xml)
Dann sieht die parent POM (ich klaue mal bei BinaryLogic):
[XML]
4.0.0
de.beispiel
beispiel-parent
pom
1.0-SNAPSHOT
Beispiel Parent Project
grundprojekt
Projekt2
Projekt3
Projekt4
[/XML]
So jetzt kann jedes Child wie folgt aussehen (ich klaue schon wieder BinaryLogic)::
[XML]
4.0.0
de.beispiel
beispiel-parent
1.0-SNAPSHOT
grundprojekt
Beispiel Child 1 Project
[/XML]
Man sieht mit einer solchen Struktur (eben Eltern-Kind) entfällt dieses lästige
<relativePath>../parentPom/</relativePath>
schlicht…(Konvention over Configuration).
Der Parent ist hier eine gute Position, um das distributionManagement festzulegen (kann man auch mit einem file:/// Zugriff machen…ABER: Bitte keine repositories festlegen…Abgesehen davon so was:
[XML]
my-group.local
my-group.local
file:${project.basedir}/…/…/Repo
[/XML]
Das bedeutet, dass jedes Projekt auf meiner Platte ein eigenes Repository erzeugt und mir die Platt voll müllt…Einfach weglassen und den Default ${HOME}/.m2/repository verwenden. Wenn der einem nicht gefällt dann in der settings.xml entsprechend anpassen.
In realen Projekten sollte der Parent von einer Corporate oder Company POM erben in der das distributionManagement definiert ist und auf einen Firmen Internen Repository Manager verweist.
Weiterhin ist mir aufgefallen, dass es eventuell günstiger ist als in diesem Beispiel (von Marco13 geklaut):
[XML]
4.0.0
<groupId>my-group</groupId>
<artifactId>project-a</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>my-group</groupId>
<artifactId>my-artifact-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../ParentPOM</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>my-group</groupId>
<artifactId>project-b</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>my-group</groupId>
<artifactId>project-c</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
[/XML]
Ich würde halt die POM wie folgt strukturieren:
[XML]
4.0.0
<parent>
<groupId>my-group</groupId>
<artifactId>my-artifact-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>project-a</artifactId>
<dependencies>
<dependency>
<groupId>my-group</groupId>
<artifactId>project-b</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>my-group</groupId>
<artifactId>project-c</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
[/XML]
Den Parent immer an den Anfang schreiben, dann sieht man sofort von wem Vererbt wird…nur die Sachen hinschreiben die auch wirklich geändert werden sollen, wie in diesem Fallen nämlich die artifactId. Version und groupId werden von der Vererbung übernommen.
Dann würde ich die Dependencies noch wie folgt anpassen:
[XML]
4.0.0
<parent>
<groupId>my-group</groupId>
<artifactId>my-artifact-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>project-a</artifactId>
<dependencies>
<dependency>
<groupId>my-group</groupId>
<artifactId>project-b</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>my-group</groupId>
<artifactId>project-c</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
[/XML]
Sprich die Versionen hier entsprechend durch Platzhalter ersetzten. Bei den einsamen beiden Dependencies bringt das nicht wirklich was…wenn aber ein Modul mal 10-20 Dependencies hat, dann sieht man sofort, dass diese Dependencies aus dem aktuellen Build sind.
Andere Abhängigkeiten sollte man zuerst in Form des dependencyManagements in den Parent einpflegen und dann in die Module übernehmen…wie z.B. :
[XML]
4.0.0
de.beispiel
beispiel-parent
1.0-SNAPSHOT
grundprojekt
Beispiel Child 1 Project
junit
junit
4.12
com.google.guava
guava
16.0.1
org.mockito
mockito-core
1.10.19
log4j
log4j
1.2.16
weitere Dependencies...
</dependencies>
[/XML]
So jetzt in den jeweiligen Projekten die Angaben entsprechend ergänzen. Und hier erst den Scope hinzufügen…Das macht es übersichtlicher…mag bei einem Projekt einfach sein, dass nur aus 5 Modulen besteht…aber überleg das mal mit einem Projekt mit 300+ Module und 5-6 Ebenen…
[XML]
4.0.0
<parent>
<groupId>my-group</groupId>
<artifactId>my-artifact-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>project-a</artifactId>
<dependencies>
<dependency>
<groupId>my-group</groupId>
<artifactId>project-b</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>my-group</groupId>
<artifactId>project-c</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</test>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</test>
</dependency>
</dependencies>
[/XML]
Wenn man konsequent ist, bedient man sich nur aus dem Parent dependencyManagement block und hält so die Versionen im Zaum…
Ein wichtiger Hinweise fehlt noch. In der Parent Pom oder besser in der Corporate POM sollten alle Plugins mit Ihren Versionen festgelegt werden… um einen reproduzierbaren Build zu bekommen.
Eine Corporate POM ist auch der Weg die Größe der POM’s für neue Projekt recht übersichtlich zu halten…
So jetzt zu den Fragen bzgl. eigenständige JAR’s bzw. Lauffähige JARs…
Das kann man durch den Einsatz von maven-assembly-plugin erreichen und damit ein sog. jar-with-dependencies bauen. Wenn man mehr Kontrolle über die Klassen bzw. Überschneidungen etc. benötigt ist hier das maven-shade-plugin das Richtige.
Hierzu sollte man aber ein eigenständiges Module hinzufügen und dort diese Aufgabe erledigen…
Wenn man Skripte zur Ausführung auf der Kommandozeile benötigt wäre hier das appassembler-maven-plugin das richtige.
Gruß
Karl Heinz Marbaise