Maven-Multimodulprojekte (= MMP = Multiprojekte) stellen eine besondere Herausforderung dar: Je nach Maven-Multimodulprojekt-Struktur und -Konfiguration funktionieren nicht mehr alle Maven-Plugins, die Zusammenarbeit mit anderen Tools wie Eclipse kann schwierig sein und der Versionierungs- und Release-Prozess kann aufwändig sein.
Wichtig ist, bei Maven-Multimodulprojekten die Unterschiede zwischen dem "Flat Project Layout" und dem "Hierarchical Project Layout" zu kennen, und die Optionen zum Versionierungs- und Release-Prozess zu berücksichtigen.
Weiter unten finden Sie konkrete Beispiele und Erläuterungen für Projekte
im "Flat Project Layout" und im "Hierarchical Project Layout".
Vorab folgt eine Gegenüberstellung einiger wichtiger Unterschiede:
Flat Project Layout | Hierarchical Project Layout | Mixed Project Layout | |
---|---|---|---|
Optimal für: | Optimal für Eclipse (aber einige Maven-Plugins funktionieren nicht) |
Optimal für Maven (aber etwas umständliche Handhabung in Eclipse) |
Funktioniert nur mit bestimmten VCS/SCM-Konstellationen |
Besondere Eigenschaft | Parallele Verzeichnisstruktur | Hierarchische Verzeichnisstruktur | Aufteilung der Parent-POM auf zwei POMs: "Multiprojekt-Root-POM" im Workspace-Root-Verzeichnis und "Master-Parent-POM" im parallelen Parent-Unterverzeichnis |
Verzeichnisstruktur und POMs |
MeinWorkspace |- Parent-Modul | '- pom.xml (Parent-POM) |- Untermodul-1 | |- pom.xml (Untermodul-1-POM) | '- src ... '- Untermodul-2 |- pom.xml (Untermodul-2-POM) '- src ... |
MeinWorkspace '- Parent-Modul |- pom.xml (Parent-POM) |- Untermodul-1 | |- pom.xml (Untermodul-1-POM) | '- src ... '- Untermodul-2 |- pom.xml (Untermodul-2-POM) '- src ... |
MeinWorkspace |- pom.xml (Multiprojekt-Root-POM) |- Parent-Modul | '- pom.xml (Master-Parent-POM) |- Untermodul-1 | |- pom.xml (Untermodul-1-POM) | '- src ... '- Untermodul-2 |- pom.xml (Untermodul-2-POM) '- src ... |
<modules>-Sektion in der Parent-pom.xml |
<artifactId>Parent-Modul</artifactId> <packaging>pom</packaging> <modules> <module>../Untermodul-1</module> <module>../Untermodul-2</module> </modules> |
<artifactId>Parent-Modul</artifactId> <packaging>pom</packaging> <modules> <module>Untermodul-1</module> <module>Untermodul-2</module> </modules> |
Zwei Parent-POMs: a) "Multiprojekt-Root-POM": Mit <modules>-Sektion wie beim Hierarchical Project Layout, zusätzlich mit <parent>-Sektion. b) "Master-Parent-POM": Ohne <modules>-Sektion. |
<parent>-Sektion in den Untermodul-pom.xml |
<parent> <artifactId>Parent-Modul</artifactId> <relativePath> ../Parent-Modul/pom.xml </relativePath> </parent> <artifactId>Untermodul...</artifactId> <packaging>jar</packaging> |
<parent> <artifactId>Parent-Modul</artifactId> </parent> <artifactId>Untermodul...</artifactId> <packaging>jar</packaging> |
Wie beim Flat Project Layout, in der <parent>-Sektion wird auf die "Master-Parent-POM" verwiesen, kein Verweis auf die "Multiprojekt-Root-POM" |
Lauffähiges Beispiel | Beispiel Flat Project Layout | Beispiel Hierarchical Project Layout | Beispiel bei Branko Juric |
DVCS-Repositories (z.B. Mercurial) | Sowohl pro Maven-Parent-Modul als auch pro Maven-Untermodul (also pro pom.xml) wird jeweils ein eigenes DVCS-Repository verwendet; Untermodule können einzeln aus- und eingecheckt werden | Pro Maven-Multimodulprojekt (inkl. aller Unterprojekte) wird nur ein einziges DVCS-Repository verwendet; es werden normalerweise alle Module des Multimodulprojekts ausgecheckt | Kann knifflig sein, je nach VCS/SCM kann es Probleme beim clone zum und commit aus dem Workspace-Root-Verzeichnis geben |
Import in Eclipse | Problemlos, es muss nicht unbedingt ein Plugin verwendet werden | Nur mit dem M2Eclipse-Plugin möglich | Wie beim Flat Project Layout |
Probleme wegen nicht eindeutiger Unterprojektnamen (z.B. in Eclipse) |
Keine Probleme, da Unterprojektnamen zwangsläufig eindeutig sind | Unterprojektnamen sind oft nicht eindeutig über verschiedene Maven-Multimodulprojekte: Dann können nicht mehrere Maven-Multimodulprojekte gleichzeitig in Eclipse importiert werden | Unterprojektnamen sind zwar zwangsläufig eindeutig, aber mehrere Maven-Multimodulprojekte gleichzeitig in einem Workspace-Verzeichnis ist aufwändig, da es nur eine Root-POM gibt |
Maven Release Plugin | Funktioniert nicht (abhängig vom VCS/SCM), siehe MRELEASE-261 | Funktioniert | Kann knifflig sein, je nach VCS/SCM kann es Probleme beim "mvn release:perform"-Kommando geben, weil das Auschecken der Untermodule nicht gelingt |
Versionierung und Release-Build | etwas aufwändiger | einfacher | wenn es funktioniert, ist die Ausführung einfacher |
Im Folgenden werden beispielhaft mehrere Maven-Projekte angelegt, um mögliche Vorgehensweisen und die Unterschiede zu erläutern. Dabei wird als Versionskontrollsystem Mercurial (hg) verwendet, aber sie sind leicht übertragbar auf andere VCS/SCM-Systeme.
Die Beispiele wurden unter Windows 7 64 Bit getestet mit JDK 8, Maven 3.3.1, Mercurial 2.0 (hg) und hgweb-Webserver 2.0 für Mercurial-Repositories.
Das Beispiel geht von einem zentralen hgweb-Webserver für
Mercurial-Repositories aus.
Falls Sie noch keinen installiert haben, siehe: hgweb-Installationsbeschreibung.
Falls Sie einen entsprechend dieser Anleitung installiert haben, starten Sie ihn über (bitte Tomcat-Pfad anpassen):
set CATALINA_HOME=D:\Tools\Tomcat-hgweb
call %CATALINA_HOME%\bin\startup.bat
Folgende Mercurial-Repositories-Struktur soll eingerichtet werden:
Die beiden Basismodule "masterpom" und "commons" sind stellvertretend für "externe Module", welche von den eigentlichen Projekten "Flat" und "Hierarchy" referenziert werden.
Zum besseren Verständnis sollten die Schritte wie im Folgenden beschrieben durchlaufen werden. Sie können auch abkürzen, indem Sie die Projektdateien downloaden.
Verzweigen Sie auf dem hgweb-Server in das Verzeichnis für Mercurial-Repositories (z.B. D:\Tools\hgweb-repos) und erzeugen Sie dort folgende Batchdatei zum Anlegen eines neuen Mercurial-Repository im hgweb-Mercurial-Repositories-Verzeichnis: run-hg-init-neuesModul.bat
@echo Batchdatei zum Anlegen eines neuen Mercurial-Repository im hgweb-Mercurial-Repositories-Verzeichnis @echo hgweb-repos-Root: %CD% @echo hgweb-Repo-Gruppe: %1 @echo Name des neuen Moduls: %2 @echo Modul-Beschreibung: %~3 @if "%~3" == "" goto _Fehler @if exist %1\%2 goto _Fehler @if not exist %1 md %1 cd %1 call hg init %2 @echo on echo [web] > %2\.hg\hgrc echo description = %~3 >> %2\.hg\hgrc echo contact = ich ^<Meine@Email.Adresse^> >> %2\.hg\hgrc cd .. type %1\%2\.hg\hgrc
Verzweigen Sie auf dem hgweb-Server in das Verzeichnis für Mercurial-Repositories und legen Sie folgendermaßen die neuen Projektrepositories an (passen Sie den Pfad D:\Tools\hgweb-repos an):
cd /D D:\Tools\hgweb-repos
call run-hg-init-neuesModul.bat Basisprojekt masterpom "Zentrale Maven-Master-POM"
call run-hg-init-neuesModul.bat Basisprojekt commons "Zentrale Common-Utilities"
call run-hg-init-neuesModul.bat Flatprojekt flat-multiproj "Flat-Multiprojekt-Parent-POM"
call run-hg-init-neuesModul.bat Flatprojekt flat-bean "Flat-Multiprojekt-Bean-Modul"
call run-hg-init-neuesModul.bat Flatprojekt flat-web "Flat-Multiprojekt-Web-Modul"
call run-hg-init-neuesModul.bat Hierarchyprojekt hierarchy-multiproj "Hierarchisches Multiprojekt"
dir
start http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi
Sie erhalten auf dem hgweb-Server folgende Mercurial-Repositories-Verzeichnisstruktur:
[D:\Tools\hgweb-repos] |- [Basisprojekt] | |- [commons] | | '- [.hg] | | '- ... | '- [masterpom] | '- [.hg] | '- ... |- [Flatprojekt] | |- [flat-bean] | | '- [.hg] | | '- ... | |- [flat-multiproj] | | '- [.hg] | | '- ... | '- [flat-web] | '- [.hg] | '- ... '- [Hierarchyprojekt] '- [hierarchy-multiproj] '- [.hg] '- ...
Und die hgweb-Webseite zeigt:
Verzweigen Sie auf Ihrem Arbeits-PC in Ihr Eclipse-Workspace-Verzeichnis (z.B. D:\MeinWorkspace), clonen Sie die neu angelegten Mercurial-Repositories und bereiten Sie Sourcecode-Verzeichnisse vor (passen Sie Pfade und URLs an):
cd /D D:\MeinWorkspace
hg clone http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Basisprojekt/masterpom
hg clone http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Basisprojekt/commons
hg clone http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Flatprojekt/flat-multiproj
hg clone http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Flatprojekt/flat-bean
hg clone http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Flatprojekt/flat-web
hg clone http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Hierarchyprojekt/hierarchy-multiproj
md commons\src\main\java\de\meinefirma\meinprojekt
md flat-bean\src\main\java\de\meinefirma\meinprojekt
md flat-bean\src\test\java\de\meinefirma\meinprojekt
md flat-web\src\main\webapp\WEB-INF
dir
Legen Sie im masterpom-Projektverzeichnis eine Datei mit den von Mercurial zu ignorierenden Dateien und Verzeichnissen an: .hgignore
syntax: glob .settings CVS logs target *.classpath *.cvsignore *.project Thumbs.db thumbs.db
Kopieren Sie diese Datei auch in die anderen Module:
cd /D D:\MeinWorkspace
copy masterpom\.hgignore commons
copy masterpom\.hgignore flat-bean
copy masterpom\.hgignore flat-multiproj
copy masterpom\.hgignore flat-web
copy masterpom\.hgignore hierarchy-multiproj
Erzeugen Sie im masterpom-Projektverzeichnis die Master-POM-Projektkonfiguration: pom.xml
<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.meinefirma.meinprojekt</groupId> <artifactId>masterpom</artifactId> <version>1.0</version> <packaging>pom</packaging> <name>masterpom</name> <properties> <hg-proj-path>Basisprojekt</hg-proj-path> <hg-base-url>http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi</hg-base-url> <scm.project.url>${hg-base-url}/${hg-proj-path}/${project.artifactId}</scm.project.url> <scm.project.connection>scm:hg:${scm.project.url}</scm.project.connection> <project.build.sourceEncoding>ISO-8859-1</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format> </properties> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-release-plugin</artifactId> <version>2.5.1</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-scm-plugin</artifactId> <version>1.9.4</version> <configuration> <tag>Tag-${project.version}</tag> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <packagingExcludes>WEB-INF/web.xml</packagingExcludes> <archive> <manifestEntries> <Modulname>${project.name}</Modulname> <Modulversion>${project.version}</Modulversion> <Maven-Build-Timestamp>${maven.build.timestamp}</Maven-Build-Timestamp> <VCS-Buildnumber>${buildNumber}</VCS-Buildnumber> <hg-ChangeSet-ID>${changeSet}, ${changeSetDate}</hg-ChangeSet-ID> </manifestEntries> </archive> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>buildnumber-maven-plugin</artifactId> <version>1.3</version> <executions> <execution> <phase>validate</phase> <goals> <goal>create</goal> <goal>hgchangeset</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>versions-maven-plugin</artifactId> <version>2.1</version> </plugin> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.2.10.v20150310</version> <configuration> <webAppConfig> <contextPath>/${project.artifactId}</contextPath> </webAppConfig> </configuration> </plugin> </plugins> </pluginManagement> </build> <dependencyManagement> <dependencies> <dependency> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>commons</artifactId> <version>2.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> </dependencyManagement> <distributionManagement> <repository> <id>DistributionRepo</id> <url>file:///D:\MeinDistributionRepo</url> </repository> <snapshotRepository> <id>DistributionRepo</id> <url>file:///D:\MeinDistributionRepo</url> </snapshotRepository> </distributionManagement> <scm> <url>${scm.project.url}</url> <connection>${scm.project.connection}</connection> <developerConnection>${scm.project.connection}</developerConnection> </scm> </project>
Bitte beachten Sie, dass bei <distributionManagement> normalerweise natürlich nicht einfach ein Verzeichnis, wie in diesem Beispiel, sondern ein Maven-Repository-Manager (z.B. Nexus) eingetragen werden sollte (falls Sie einen installiert haben).
Erzeugen Sie im commons-Projektverzeichnis die commons-Projektkonfiguration: pom.xml
<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> <parent> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>masterpom</artifactId> <version>1.0</version> <relativePath>../masterpom/pom.xml</relativePath> </parent> <artifactId>commons</artifactId> <version>2.0</version> <packaging>jar</packaging> <name>commons</name> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> </dependencies> <scm> <url>${scm.project.url}</url> <connection>${scm.project.connection}</connection> <developerConnection>${scm.project.connection}</developerConnection> </scm> </project>
Erzeugen Sie im commons\src\main\java\de\meinefirma\meinprojekt-Verzeichnis die Java-Klasse: MeinUtil.java
package de.meinefirma.meinprojekt; public class MeinUtil { public static int meineUtilMethode( int i1, int i2 ) { return i1 + i2; } }
Überprüfen Sie folgendermaßen, dass <connection> und <developerConnection> im <scm>-Abschnitt zu korrekten Mercurial-hgweb-URIs aufgelöst wird:
cd /D D:\MeinWorkspace\masterpom
mvn help:effective-pom
mvn help:effective-pom | find /I "connection"
<connection>scm:hg:http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Basisprojekt/masterpom</connection> <developerConnection>scm:hg:http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Basisprojekt/masterpom</developerConnection>
cd /D D:\MeinWorkspace\commons
mvn help:effective-pom | find /I "connection"
<connection>scm:hg:http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Basisprojekt/commons</connection> <developerConnection>scm:hg:http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Basisprojekt/commons</developerConnection>
Erzeugen Sie im flat-multiproj-Projektverzeichnis die flat-multiproj-Projektkonfiguration: pom.xml
<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> <parent> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>masterpom</artifactId> <version>1.0</version> <relativePath>../masterpom/pom.xml</relativePath> </parent> <artifactId>flat-multiproj</artifactId> <version>3.0-SNAPSHOT</version> <packaging>pom</packaging> <name>flat-multiproj</name> <modules> <module>../flat-bean</module> <module>../flat-web</module> </modules> <properties> <hg-proj-path>Flatprojekt</hg-proj-path> </properties> <scm> <url>${scm.project.url}</url> <connection>${scm.project.connection}</connection> <developerConnection>${scm.project.connection}</developerConnection> </scm> </project>
Erzeugen Sie im flat-bean-Projektverzeichnis die flat-bean-Projektkonfiguration: pom.xml
<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> <parent> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>flat-multiproj</artifactId> <version>3.0-SNAPSHOT</version> <relativePath>../flat-multiproj/pom.xml</relativePath> </parent> <artifactId>flat-bean</artifactId> <packaging>jar</packaging> <name>flat-bean</name> <dependencies> <dependency> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>commons</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> </dependencies> </project>
Erzeugen Sie im flat-web-Projektverzeichnis die flat-web-Projektkonfiguration: pom.xml
<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> <parent> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>flat-multiproj</artifactId> <version>3.0-SNAPSHOT</version> <relativePath>../flat-multiproj/pom.xml</relativePath> </parent> <artifactId>flat-web</artifactId> <packaging>war</packaging> <name>flat-web</name> <build> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>buildnumber-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>flat-bean</artifactId> <version>${project.version}</version> </dependency> </dependencies> </project>
Erzeugen Sie im flat-bean\src\main\java\de\meinefirma\meinprojekt-Verzeichnis die Java-Klasse: MeineBean.java
package de.meinefirma.meinprojekt; public class MeineBean { public static int berechne( int i1, int i2 ) { return MeinUtil.meineUtilMethode( i1, i2 ); } }
Erzeugen Sie im flat-bean\src\test\java\de\meinefirma\meinprojekt-Verzeichnis den JUnit-Test: MeineBeanTest.java
package de.meinefirma.meinprojekt; import org.junit.*; public class MeineBeanTest { @Test public void testMeineBean() { Assert.assertEquals( 3, MeineBean.berechne( 1, 2 ) ); } }
Erzeugen Sie im flat-web\src\main\webapp-Verzeichnis die JSP: index.jsp
<%@ page import="java.io.*" %> <%@ page import="java.util.*" %> <%@ page import="java.util.jar.*" %> <%@ page import="de.meinefirma.meinprojekt.MeineBean" %> <html> <body> <h2>Hello World!</h2> <% String pth = getServletConfig().getServletContext().getRealPath( "/" ); if( !pth.endsWith( "/" ) && !pth.endsWith( "\\" ) ) pth += "/"; File mf = new File( pth + "META-INF/MANIFEST.MF" ); if( mf.exists() ) { out.println( "<h4>Attribute in der META-INF/MANIFEST.MF:</h4>" ); Manifest manifest = new Manifest( new FileInputStream( mf ) ); for( Map.Entry<Object,Object> attr : manifest.getMainAttributes().entrySet() ) { out.println( attr + "<br>" ); } } out.println( "<h4>MeineBean:</h4>MeineBean.berechne( 1, 2 ): " + MeineBean.berechne( 1, 2 ) ); %> </body> </html>
Erzeugen Sie im flat-web\src\main\webapp\WEB-INF-Verzeichnis die Webapp-Konfiguration: web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
Erzeugen Sie im flat-multiproj-Projektverzeichnis die Batchdatei: run-webapp.bat
@echo. @pushd . cd ..\masterpom call mvn clean install @echo on if errorlevel 1 goto _Fehler @echo. cd ..\commons call mvn clean install @echo on if errorlevel 1 goto _Fehler @echo. cd ..\flat-multiproj call mvn clean install @echo on if errorlevel 1 goto _Fehler cd ..\flat-web start cmd /C mvn jetty:run-war @ping -n 10 127.0.0.1 >nul start http://localhost:8080/flat-web @echo. type target\flat-web\META-INF\MANIFEST.MF :_Fehler @popd @echo.
Überprüfen Sie folgendermaßen, dass <connection> und <developerConnection> im <scm>-Abschnitt zu korrekten Mercurial-hgweb-URIs aufgelöst wird:
cd /D D:\MeinWorkspace\flat-multiproj
mvn help:evaluate -Dexpression=pom.scm.connection | findstr /V [
scm:hg:http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Flatprojekt/flat-multiproj
cd /D D:\MeinWorkspace\flat-bean
mvn help:evaluate -Dexpression=pom.scm.connection | findstr /V [
scm:hg:http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Flatprojekt/flat-bean
cd /D D:\MeinWorkspace\flat-web
mvn help:evaluate -Dexpression=pom.scm.connection | findstr /V [
scm:hg:http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Flatprojekt/flat-web
Überprüfen Sie Ihre Workspace-Verzeichnisse:
cd /D D:\MeinWorkspace
tree /F
[\MeinWorkspace] |- [commons] | |- .hgignore | |- pom.xml | |- [.hg] | | '- ... | '- [src] | '- [main] | '- [java] | '- [de] | '- [meinefirma] | '- [meinprojekt] | '- MeinUtil.java |- [flat-bean] | |- .hgignore | |- pom.xml | |- [.hg] | | '- ... | '- [src] | |- [main] | | '- [java] | | '- [de] | | '- [meinefirma] | | '- [meinprojekt] | | '- MeineBean.java | '- [test] | '- [java] | '- [de] | '- [meinefirma] | '- [meinprojekt] | '- MeineBeanTest.java |- [flat-multiproj] | |- .hgignore | |- pom.xml | |- run-webapp.bat | '- [.hg] | '- ... |- [flat-web] | |- .hgignore | |- pom.xml | |- [.hg] | | '- ... | '- [src] | '- [main] | '- [webapp] | |- index.jsp | '- [WEB-INF] | '- web.xml |- [hierarchy-multiproj] | |- .hgignore | '- [.hg] | '- ... '- [masterpom] |- .hgignore |- pom.xml '- [.hg] '- ...
Da bisher nur Module im "Flat Project Layout" angelegt wurden, liegen alle pom.xml-Dateien in direkten Unterverzeichnissen zum Eclipse-Workspace-Verzeichnis. Es gibt noch keine hierarchisch angeordnete "nested" Module, wie auch das folgende Kommando zeigt:
cd /D D:\MeinWorkspace
dir pom.xml /B /S
D:\MeinWorkspace\commons\pom.xml D:\MeinWorkspace\flat-bean\pom.xml D:\MeinWorkspace\flat-multiproj\pom.xml D:\MeinWorkspace\flat-web\pom.xml D:\MeinWorkspace\masterpom\pom.xml
Der bisherige Entwicklungsstand wird in die Mercurial-Repositories gesichert:
cd /D D:\MeinWorkspace
cd masterpom
hg add
hg commit -m "add: pom.xml"
hg push
cd ..\commons
hg add
hg commit -m "add: pom.xml + MeinUtil.java"
hg push
cd ..\flat-multiproj
hg add
hg commit -m "add: pom.xml"
hg push
cd ..\flat-bean
hg add
hg commit -m "add: pom.xml + MeineBean.java + MeineBeanTest.java"
hg push
cd ..\flat-web
hg add
hg commit -m "add: pom.xml + index.jsp + web.xml"
hg push
cd ..
Testen Sie die Webapp:
cd /D D:\MeinWorkspace\flat-multiproj
run-webapp.bat
Die Module werden compiliert, der JUnit-Test wird ausgeführt, die Ergebnis-Artefakte werden ins lokale Maven-Repository gespeichert, der Jetty-Webserver wird gestartet und es wird die Ergebnis-Webseite angezeigt:
Hello World! Attribute in der META-INF/MANIFEST.MF: Modulname=flat-web Modulversion=3.0-SNAPSHOT VCS-Buildnumber=ba710a8a8d70 hg-ChangeSet-ID=ba710a8a8d70, 2012-02-26 16:04 +0100 Maven-Build-Timestamp=2012-02-26 16:06 ... MeineBean: MeineBean.berechne( 1, 2 ): 3
Die Webseite ruft MeineBean.berechne() aus dem flat-bean-Modul auf und zeigt den Inhalt der in der flat-web\target\flat-web.war gespeicherten MANIFEST.MF-Datei. Darin enthalten sind u.a.: Die Version 3.0-SNAPSHOT, die Mercurial-ChangeSet-ID und der Build-Timestamp.
Zusätzlich zum bisher angelegten Project im Flat-Layout wird dieses Projekt ein zweites Mal angelegt, aber diesmal im Hierarchical-Layout. Da die Funktionalität dieselbe sein soll, kopieren wir die Sourcedateien vom Flat-Projekt:
cd /D D:\MeinWorkspace
copy flat-multiproj\pom.xml hierarchy-multiproj
xcopy flat-bean\src hierarchy-multiproj\hierarchy-bean\src\ /S
xcopy flat-web\src hierarchy-multiproj\hierarchy-web\src\ /S
cd hierarchy-multiproj
tree /F
Öffnen Sie die hierarchy-multiproj\pom.xml und ersetzen Sie den Abschnitt:
<artifactId>flat-multiproj</artifactId> <version>3.0-SNAPSHOT</version> <packaging>pom</packaging> <name>flat-multiproj</name> <modules> <module>../flat-bean</module> <module>../flat-web</module> </modules> <properties> <hg-proj-path>Flatprojekt</hg-proj-path> </properties>
durch:
<artifactId>hierarchy-multiproj</artifactId> <version>4.0-SNAPSHOT</version> <packaging>pom</packaging> <name>hierarchy-multiproj</name> <modules> <module>hierarchy-bean</module> <module>hierarchy-web</module> </modules> <properties> <hg-proj-path>Hierarchyprojekt</hg-proj-path> </properties>
Beachten Sie, dass bei den Untermodulen das vorangestellte "../" entfällt.
Erzeugen Sie im hierarchy-multiproj\hierarchy-bean-Verzeichnis die Projektkonfiguration: pom.xml
<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> <parent> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>hierarchy-multiproj</artifactId> <version>4.0-SNAPSHOT</version> </parent> <artifactId>hierarchy-bean</artifactId> <packaging>jar</packaging> <name>hierarchy-bean</name> <dependencies> <dependency> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>commons</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> </dependencies> <scm> <url>${scm.project.url}</url> <connection>${scm.project.connection}</connection> <developerConnection>${scm.project.connection}</developerConnection> </scm> </project>
Beachten Sie, dass für das Parent-Modul kein <relativePath> angegeben wird.
Erzeugen Sie im hierarchy-multiproj\hierarchy-web-Verzeichnis die Projektkonfiguration: pom.xml
<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> <parent> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>hierarchy-multiproj</artifactId> <version>4.0-SNAPSHOT</version> </parent> <artifactId>hierarchy-web</artifactId> <packaging>war</packaging> <name>hierarchy-web</name> <build> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>buildnumber-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>hierarchy-bean</artifactId> <version>${project.version}</version> </dependency> </dependencies> <scm> <url>${scm.project.url}</url> <connection>${scm.project.connection}</connection> <developerConnection>${scm.project.connection}</developerConnection> </scm> </project>
Erzeugen Sie im hierarchy-multiproj-Verzeichnis die Batchdatei: run-webapp.bat
@echo. @pushd . cd ..\masterpom call mvn clean install @echo on if errorlevel 1 goto _Fehler @echo. cd ..\commons call mvn clean install @echo on if errorlevel 1 goto _Fehler @echo. cd ..\hierarchy-multiproj call mvn clean install @echo on if errorlevel 1 goto _Fehler cd hierarchy-web start cmd /C mvn jetty:run-war @ping -n 10 127.0.0.1 >nul start http://localhost:8080/hierarchy-web @echo. type target\hierarchy-web\META-INF\MANIFEST.MF :_Fehler @popd @echo.
Überprüfen Sie folgendermaßen, dass <connection> und <developerConnection> im <scm>-Abschnitt zu korrekten Mercurial-hgweb-URIs aufgelöst wird:
cd /D D:\MeinWorkspace\hierarchy-multiproj
mvn help:evaluate -Dexpression=pom.scm.connection | findstr /V [
scm:hg:http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Hierarchyprojekt/hierarchy-multiproj
cd /D D:\MeinWorkspace\hierarchy-multiproj\hierarchy-bean
mvn help:evaluate -Dexpression=pom.scm.connection | findstr /V [
scm:hg:http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Hierarchyprojekt/hierarchy-bean
cd /D D:\MeinWorkspace\hierarchy-multiproj\hierarchy-web
mvn help:evaluate -Dexpression=pom.scm.connection | findstr /V [
scm:hg:http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Hierarchyprojekt/hierarchy-web
Überprüfen Sie Ihre Projektverzeichnisse:
cd /D D:\MeinWorkspace\hierarchy-multiproj
tree /F
[\MeinWorkspace] |- [commons] | '- ... |- [flat-bean] | '- ... |- [flat-multiproj] | '- ... |- [flat-web] | '- ... |- [hierarchy-multiproj] | |- .hgignore | |- pom.xml | |- run-webapp.bat | |- [.hg] | | '- ... | |- [hierarchy-bean] | | |- pom.xml | | '- [src] | | |- [main] | | | '- [java] | | | '- [de] | | | '- [meinefirma] | | | '- [meinprojekt] | | | '- MeineBean.java | | '- [test] | | '- [java] | | '- [de] | | '- [meinefirma] | | '- [meinprojekt] | | '- MeineBeanTest.java | '- [hierarchy-web] | |- pom.xml | '- [src] | '- [main] | '- [webapp] | |- index.jsp | '- [WEB-INF] | '- web.xml '- [masterpom] '- ...
Während beim Flat-Projekt die Untermodule flat-bean und flat-web parallel zum Parent-Modul flat-multiproj angeordnet sind, sind beim Hierarchy-Projekt die Untermodule hierarchy-bean und hierarchy-web unterhalb zum Parent-Modul hierarchy-multiproj angeordnet. Ein weiterer Unterschied ist, dass die drei Module des Flat-Projekts in drei jeweils eigenen Mercurial-Repositories gesichert sind, während die drei Module des Hierarchy-Projekts in einem einzigen Mercurial-Repositories gesichert sind. Sehen Sie sich die Verzeichnisse der pom.xml-Dateien an:
cd /D D:\MeinWorkspace
dir pom.xml /B /S
D:\MeinWorkspace\commons\pom.xml D:\MeinWorkspace\flat-bean\pom.xml D:\MeinWorkspace\flat-multiproj\pom.xml D:\MeinWorkspace\flat-web\pom.xml D:\MeinWorkspace\hierarchy-multiproj\pom.xml D:\MeinWorkspace\hierarchy-multiproj\hierarchy-bean\pom.xml D:\MeinWorkspace\hierarchy-multiproj\hierarchy-web\pom.xml D:\MeinWorkspace\masterpom\pom.xml
Sichern Sie den Entwicklungsstand ins Mercurial-Repository:
cd /D D:\MeinWorkspace\hierarchy-multiproj
hg add
hg commit -m "add: 3 x pom.xml + MeineBean.java + MeineBeanTest.java + index.jsp + web.xml"
hg push
Testen Sie auch diese Webapp:
cd /D D:\MeinWorkspace\hierarchy-multiproj
run-webapp.bat
Die Module werden compiliert, der JUnit-Test wird ausgeführt, die Ergebnis-Artefakte werden ins lokale Maven-Repository gespeichert, der Jetty-Webserver wird gestartet und es wird wieder die oben erläuterte Ergebnis-Webseite angezeigt.
Sehen Sie sich die für einen typischen Release-Prozess benötigten Schritte an.
Sehen Sie sich die Dokus zu den drei Maven-Plugins Maven SCM Plugin, Maven Release Plugin und Versions Maven Plugin an.
Voraussetzung für die folgenden Beispiele sind die beiden in den letzten Beispielen angelegten Projekte "Flat Project Layout" und "Hierarchical Project Layout". Falls Sie abkürzen wollen, können Sie die Projektdateien downloaden.
Überprüfen Sie, dass Ihr hgweb-Webserver für Mercurial-Repositories aktiv ist, zum Beispiel durch Aufruf der hgweb-Webserver-URL,
beispielsweise
http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi.
Falls er noch nicht gestartet ist, starten Sie ihn, beispielsweise im Falle der oben beschriebenen Installation über:
set CATALINA_HOME=D:\Tools\Tomcat-hgweb
call %CATALINA_HOME%\bin\startup.bat
Bitte führen Sie zuerst das zu Ihrem lokalen Maven-Repository-Verzeichnis passende set-Kommando aus:
set MEIN_PROJ_REPO=%USERPROFILE%\.m2\repository\de\meinefirma\meinprojekt
bzw.
set MEIN_PROJ_REPO=D:\Tools\Maven3-Repo\de\meinefirma\meinprojekt
Überprüfen Sie die Environmentvariable mit:
tree %MEIN_PROJ_REPO%
Falls Sie bereits alle Projekte vollständig gebaut haben, erhalten Sie:
...\de\meinefirma\meinprojekt |- commons | '- 2.0 |- flat-bean | '- 3.0-SNAPSHOT |- flat-multiproj | '- 3.0-SNAPSHOT |- flat-web | '- 3.0-SNAPSHOT |- hierarchy-bean | '- 4.0-SNAPSHOT |- hierarchy-multiproj | '- 4.0-SNAPSHOT |- hierarchy-web | '- 4.0-SNAPSHOT '- masterpom '- 1.0
Um die Übersichtlichkeit zu erhöhen, sollten Sie die bisherigen Artefakte löschen:
rd /S /Q %MEIN_PROJ_REPO%
Erstellen Sie das leere Distributionsverzeichnis (so wie in der masterpom-pom.xml unter <distributionManagement> deklariert, als Test-Ersatz für einen Maven-Repository-Manager) und setzen Sie eine entsprechende Environmentvariable:
set MEIN_DISTRIBUTION_REPO=D:\MeinDistributionRepo
md %MEIN_DISTRIBUTION_REPO%
Bauen Sie die beiden verwendeten Basisprojekte:
cd /D D:\MeinWorkspace\masterpom
mvn clean install
cd /D D:\MeinWorkspace\commons
mvn clean install
tree %MEIN_PROJ_REPO%
Falls Sie bei den folgenden Schritten auf diese Fehlermeldung stoßen:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-release-plugin:2.5.1:prepare (default-cli) on project ...: Failed to invoke Maven build. Error configuring command-line. Reason: Maven executable not found at: ...\bin\mvn.bat
Dann prüfen Sie, ob sich in Ihrem Maven-bin-Verzeichnis eine mvn.bat-Datei befindet. Falls nicht, führen Sie aus:
cd /D %M2_HOME%\bin
dir mvn.*
if not exist mvn.bat copy mvn.cmd mvn.bat
Falls Sie das Versionskontrollsystem CVS verwenden und Maven-SCM-Kommandos Probleme mit der Authentifizierung haben, z.B. mit einer Fehlermeldung ähnlich zu:
[ERROR] Didn't find password ...
org.netbeans.lib.cvsclient.connection.AuthenticationException: Wrong Password
org.apache.maven.scm.ScmException: password is required
Dann überprüfen Sie Ihre
.cvspass-Datei.
Eventuell hilft auch:
-Dmaven.scm.provider.cvs.implementation=cvs_native.
Mit dem Hierarchyprojekt funktioniert das Maven Release Plugin hervorragend, wie im Folgenden demonstriert wird. Falls Sie nicht Mercurial verwenden, sondern ein anderes VCS/SCM-System, müssen Sie lediglich die "hg ..."-Kommandos durch entsprechende "mvn scm:..."-Kommandos ersetzen.
Führen Sie die obigen Vorbereitungen durch, inklusive des Setzens der MEIN_PROJ_REPO- und MEIN_DISTRIBUTION_REPO-Umgebungsvariablen.
Falls Sie Ihr Projekt noch nicht aus dem hgweb-Webserver-Mercurial-Repository kopiert haben, clonen Sie es:
cd /D D:\MeinWorkspace
hg clone http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Hierarchyprojekt/hierarchy-multiproj
Die Änderung der Versionsbezeichnung zu einer Release-Version (ohne "-SNAPSHOT"), der Release-Build mit dieser Release-Version und die Erhöhung der Versionsnummer auf die nächsthöhere Entwicklerversion (wieder mit "-SNAPSHOT") erfolgen im Wesentlichen über die beiden Maven-Release-Plugin-Kommandos:
mvn --batch-mode release:prepare
mvn release:perform
Aber um die Vorgänge besser zu verstehen, werden im Folgenden noch weitere Kommandos ausgeführt.
Führen Sie folgende Kommandos aus und beobachten Sie die Ergebnisse:
Ausgeführte Kommandos | Version in den POMs im Workspace | Versionen in hg-Repositories (lokal + hgweb) | Versionen im lokalen Maven-Repository | Versionen im Distribution-Repository |
---|---|---|---|---|
cd /D D:\MeinWorkspace\hierarchy-multiproj type pom.xml tree %MEIN_PROJ_REPO% tree %MEIN_DISTRIBUTION_REPO% mvn scm:status hg status |
4.0-SNAPSHOT | 4.0-SNAPSHOT | [eventuell 4.0-SNAPSHOT] |
[leer] |
mvn release:prepare -DdryRun=true Bestätigen Sie 7 mal die Vorgabewerte oder Ihre Eingaben. mvn release:clean |
4.0-SNAPSHOT | 4.0-SNAPSHOT | [eventuell 4.0-SNAPSHOT] |
[leer] |
mvn --batch-mode release:prepare |
||||
type pom.xml hg log hg tags hg status |
4.1-SNAPSHOT | 4.0-SNAPSHOT 4.0 4.1-SNAPSHOT |
[eventuell 4.0-SNAPSHOT] |
[leer] |
mvn release:perform |
||||
tree %MEIN_PROJ_REPO% tree %MEIN_DISTRIBUTION_REPO% hg status |
4.1-SNAPSHOT | 4.0-SNAPSHOT 4.0 4.1-SNAPSHOT |
[eventuell 4.0-SNAPSHOT] 4.0 |
4.0 |
Ergebnis:
Mit dem Flatprojekt funktioniert das Maven Release Plugin nicht zusammen mit Mercurial. Deshalb wird das Versions Maven Plugin eingesetzt. Falls Sie nicht Mercurial verwenden, sondern ein anderes VCS/SCM-System, müssen Sie auch hier wieder lediglich die "hg ..."-Kommandos durch entsprechende "mvn scm:..."-Kommandos ersetzen (siehe hierzu auch das anschließend folgende Beispiel).
Führen Sie die obigen Vorbereitungen durch, inklusive des Setzens der MEIN_PROJ_REPO- und MEIN_DISTRIBUTION_REPO-Umgebungsvariablen.
Falls Sie die Module des Flatprojekts noch nicht aus dem hgweb-Webserver-Mercurial-Repository kopiert haben, clonen Sie sie:
cd /D D:\MeinWorkspace
hg clone http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Flatprojekt/flat-multiproj
hg clone http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Flatprojekt/flat-bean
hg clone http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Flatprojekt/flat-web
Führen Sie folgende Kommandos aus und beobachten Sie die Ergebnisse:
Ausgeführte Kommandos | Version in den POMs im Workspace | Versionen in hg-Repositories (lokal + hgweb) | Versionen im lokalen Maven-Repository | Versionen im Distribution-Repository |
---|---|---|---|---|
cd /D D:\MeinWorkspace\flat-multiproj type pom.xml type ..\flat-bean\pom.xml tree %MEIN_PROJ_REPO% tree %MEIN_DISTRIBUTION_REPO% |
3.0-SNAPSHOT | 3.0-SNAPSHOT | [eventuell 3.0-SNAPSHOT] |
[leer] |
mvn versions:set -DnewVersion=3.0 mvn versions:commit |
||||
type pom.xml type ..\flat-bean\pom.xml hg status hg diff |
3.0 | 3.0-SNAPSHOT | [eventuell 3.0-SNAPSHOT] |
[leer] |
cd ..\flat-bean hg commit -m "Release 3.0" hg tag TAG_FLAT_3.0 hg push cd ..\flat-web hg commit -m "Release 3.0" hg tag TAG_FLAT_3.0 hg push cd ..\flat-multiproj hg commit -m "Release 3.0" hg tag TAG_FLAT_3.0 hg push |
||||
hg log hg tags |
3.0 | 3.0-SNAPSHOT 3.0 |
[eventuell 3.0-SNAPSHOT] |
[leer] |
mvn deploy |
||||
tree %MEIN_PROJ_REPO% tree %MEIN_DISTRIBUTION_REPO% |
3.0 | 3.0-SNAPSHOT 3.0 |
[eventuell 3.0-SNAPSHOT] 3.0 |
3.0 |
mvn versions:set -DnewVersion=3.1-SNAPSHOT mvn versions:commit |
||||
type pom.xml hg status hg diff |
3.1-SNAPSHOT | 3.0-SNAPSHOT 3.0 |
[eventuell 3.0-SNAPSHOT] 3.0 |
3.0 |
cd ..\flat-bean hg commit -m "3.1-SNAPSHOT" hg push cd ..\flat-web hg commit -m "3.1-SNAPSHOT" hg push cd ..\flat-multiproj hg commit -m "3.1-SNAPSHOT" hg push |
||||
hg log |
3.1-SNAPSHOT | 3.0-SNAPSHOT 3.0 3.1-SNAPSHOT |
[eventuell 3.0-SNAPSHOT] 3.0 |
3.0 |
Falls Sie folgende Exception erhalten:
Execution default-cli of goal org.codehaus.mojo:versions-maven-plugin:2.2:set failed. NullPointerException
Dann verwenden Sie das versions-maven-plugin in der Version 2.2. Diese Version hat unter bestimmten Umständen einen Fehler, den die Version 2.1 nicht hat, siehe NullPointerException in versions:set. Ersetzen Sie in diesem Fall das Kommando:
mvn versions:set -DnewVersion=...
durch:
mvn org.codehaus.mojo:versions-maven-plugin:2.1:set -DnewVersion=...
Wie das letzte Beispiel zeigt, sind anders als beim "Hierarchical Project Layout" beim "Flat Project Layout" mehr einzelne Schritte notwendig. Insbesondere müssen das Einchecken und das Tag-Setzen in jedem Untermodulverzeichnis einzeln erfolgen. Hierzu wird im Folgenden eine unter Windows lauffähige Batchdatei vorgestellt, die das in einem einzigen Aufruf bewerkstelligt.
Diese Batchdatei ist nicht auf Mercurial festgelegt, sondern für beliebige VCS/SCM-Systeme ausgelegt. Voraussetzung sind korrekte an Ihr VCS/SCM-System angepasste SCM-Konfigurationseinträge in den <SCM>-Rubriken in der masterpom-pom.xml und den Modulen.
Die Batchdatei funktioniert auch dann, wenn es außer den zum Multimodul-Projekt gehörenden Modulverzeichnissen noch weitere Verzeichnisse gibt, die nicht modifiziert werden dürfen. Hierzu wird geprüft, ob die Module die artifactId der Parent-POM entweder enthalten oder darauf verweisen.
Erstellen Sie im Parent-Verzeichnis, also im Flatprojekt-Beispiel in \MeinWorkspace\flat-multiproj, die Batchdatei: run-createRelease.bat
cls @title %~n0 @pushd . @echo. @echo ---------------------------------------------------------------------------------------- @echo Batchdatei fuer Release-Prozess fuer Maven-Multimodulprojekte im "Flat Project Layout". @echo Folgende Schritte werden ausgefuehrt: @echo 1. Setzen der neuen Release-Versionsnummer @echo 2. Commit ins VCS/SCM @echo 3. Setzen eines Tags im VCS/SCM @echo 4. Erstellen und deployen der Ergebnis-Artefakte @echo 5. Setzen der neuen Entwicklungs-Snapshot-Versionsnummer @echo 6. Commit ins VCS/SCM @echo ---------------------------------------------------------------------------------------- @echo Diese Batchdatei muss im Parent-Modul-Verzeichnis ausgefuehrt werden. @echo Als Parameter muessen uebergeben werden: @echo 1. Parameter: die neue Release-Versionsnummer (ohne -SNAPSHOT), z.B.: 1.2.3 @echo 2. Parameter: die neue Entwicklungs-Versionsnummer (mit -SNAPSHOT), z.B.: 1.2.4-SNAPSHOT @echo ---------------------------------------------------------------------------------------- @echo. @echo. @echo -------- Parameter ueberpruefen: @set _startDir=%CD% @if "%2" == "" goto _Fehler @for /f "delims=" %%a in ('call mvn help:evaluate -Dexpression^=pom.artifactId ^| findstr /V [') do @set _mmp_afid=%%a @set _mmp_afid_tag=^^^<artifactId^^^>%_mmp_afid%^^^</artifactId^^^> @echo Neue Release-Versionsnummer: %1 @echo Neue Entwicklungs-Versionsnummer: %2 @echo Startverzeichnis: %_startDir% @echo MMP-artifactId: %_mmp_afid% @echo MMP-Tag-Suchstring: %_mmp_afid_tag% @echo. call mvn scm:validate @if errorlevel 1 goto _Fehler @echo. @echo. @echo -------- Setzen der neuen Release-Versionsnummer %1 fuer alle Module gemeinsam @echo. call :setzeVersion %1 @if errorlevel 1 goto _Fehler @echo. @echo. @echo -------- Die Module mit Version %1 einzeln einchecken und taggen @echo. cd .. call :checkinAndTag %1 tag @if errorlevel 1 goto _Fehler cd %_startDir% @echo. @echo. @echo -------- Erstellen und deployen der Ergebnis-Artefakte mit Version %1 @echo. call mvn clean deploy @if errorlevel 1 goto _Fehler @echo. @echo. @echo -------- Setzen der neuen Entwicklungs-Versionsnummer %2 fuer alle Module gemeinsam @echo. call :setzeVersion %2 @if errorlevel 1 goto _Fehler @echo. @echo. @echo -------- Die Module mit Version %2 einzeln einchecken (ohne Tag) @echo. cd .. call :checkinAndTag %2 @if errorlevel 1 goto _Fehler cd %_startDir% @echo. @echo. @echo -------- changelog und status @echo. call mvn scm:changelog | findstr /V [ @echo. call mvn scm:status | findstr /V [ @echo. @echo --------------------------- @echo ++++ Erfolgreich ++++ @echo --------------------------- @echo @goto _fertig :setzeVersion @echo. call mvn help:evaluate -Dexpression=pom.version | findstr /V [ call mvn versions:set -DnewVersion=%1 @if errorlevel 1 exit /B 1 call mvn versions:commit @if errorlevel 1 exit /B 1 @echo. call mvn help:evaluate -Dexpression=pom.version | findstr /V [ @echo. exit /B 0 :checkinAndTag @echo off @echo. FOR /F %%i in ('dir /B /A:D') DO ( @echo. cd %%i @echo Aktuelles Unterverzeichnis: %%i if not exist pom.xml ( @echo --- Info: %%i enthaelt keine 'pom.xml', deshalb keine Aktion. ) else ( findstr %_mmp_afid_tag% pom.xml > nul if errorlevel 1 ( @echo --- Info: Die pom.xml in %%i enthaelt nicht den String %_mmp_afid_tag%, deshalb keine Aktion. ) else ( @echo. @echo --- Info: %%i wird eingecheckt call mvn scm:checkin -Dmessage="Version %1" @if errorlevel 1 exit /B 1 if not "%2" == "" ( @echo --- Info: %%i erhaelt ein Tag call mvn scm:tag @if errorlevel 1 exit /B 1 ) ) ) @echo off cd .. ) exit /B 0 :_Fehler @echo. @echo ###################### @echo #### FEHLER #### @echo ###################### @echo pause :_fertig cd %_startDir% @popd @title %~dp0
Führen Sie die obigen Vorbereitungen durch, inklusive des Setzens der MEIN_PROJ_REPO- und MEIN_DISTRIBUTION_REPO-Umgebungsvariablen (die Umgebungsvariablen werden nicht für die Batchdatei benötigt, aber im folgenden Beispiel für die zusätzlichen Test-Kommandos).
Führen Sie folgende Kommandos aus und beobachten Sie die Ergebnisse:
Ausgeführte Kommandos | Version in den POMs im Workspace | Versionen in hg-Repositories (lokal + hgweb) | Versionen im lokalen Maven-Repository | Versionen im Distribution-Repository |
---|---|---|---|---|
Überprüfen Sie die Ausgangssituation: cd /D D:\MeinWorkspace\flat-multiproj type pom.xml type ..\flat-bean\pom.xml tree %MEIN_PROJ_REPO% tree %MEIN_DISTRIBUTION_REPO% |
3.1-SNAPSHOT | 3.0-SNAPSHOT 3.0 3.1-SNAPSHOT |
3.0 | 3.0 |
cd /D D:\MeinWorkspace\flat-multiproj run-createRelease.bat 3.5 3.6-SNAPSHOT |
||||
tree %MEIN_PROJ_REPO% tree %MEIN_DISTRIBUTION_REPO% type pom.xml hg log hg tags (Führen Sie die letzten drei Kommandos auch |
3.6-SNAPSHOT | 3.0-SNAPSHOT 3.0 3.1-SNAPSHOT 3.5 3.6-SNAPSHOT |
3.0 3.5 |
3.0 3.5 |
Das Importieren in Eclipse von Maven-Multimodulprojekten aus einem Mercurial-Repository kann schon mal etwas knifflig sein. Beachten Sie dabei Folgendes:
Das folgende Beispiel wurde unter Windows 7 64 Bit getestet mit:
Um auch etwas schwierigere Fälle abzudecken, wird ein etwas umständlicher aber dafür oft erfolgreicher Weg beschrieben:
Überprüfen Sie in Eclipse die M2Eclipse-Plugin-Settings unter:
"Window | Preferences | Maven | User Settings", möglicherweise so (passen Sie die Pfade an):
User Settings File: | C:\Users\User\.m2\settings.xml |
Local Repository: | C:\Users\User\.m2\repository |
Oder so:
User Settings File: | D:\Tools\Maven3\conf\settings.xml |
Local Repository: | D:\Tools\Maven3-Repo |
Importieren Sie in Eclipse zuerst über das MercurialEclipse-Plugin (passen Sie die URL an):
File | Import... | Mercurial | Clone Existing Mercurial Repository |
http://localhost:4419/hgweb/cgi-bin/meinprojekt.cgi/Hierarchyprojekt/hierarchy-multiproj
Anschließend löschen Sie das gerade geladene Projekt im Eclipse Package Explorer wieder, aber nur im Package Explorer und nicht auf der Festplatte (ausgeschaltet: "Delete project contents on disk").
Jetzt importieren Sie über das M2Eclipse-Plugin (passen Sie den Pfad an):
File | Import... | Maven | Existing Maven Projects | D:\MeinWorkspace
Anschließend generieren Sie die Eclipse-Projektkonfiguration:
Im Eclipse Package Explorer die Projekte markieren | rechte Maustaste | Maven | Update Project Configuration.
Kontrollieren Sie die Mercurial-Parameter:
Im Eclipse Package Explorer ein Projekt markieren | rechte Maustaste | Properties | Mercurial.
Sehen Sie sich die in Eclipse verwendeten Mercurial-Repositories an über:
Window | Show View | Mercurial Repositories.
Wenn Sie so nacheinander alle weiter oben erzeugten Projekte importieren, zeigt Eclipse:
Bitte beachten Sie:
Sehen Sie sich bei Problemen die weiteren Hinweise zum M2Eclipse-Plugin an.
Eine alternative Vorgehensweise wird beschrieben unter: Using maven-eclipse-plugin in multi-module projects with WTP.
Hierzu siehe: Maven-Multimodulprojekte in IntelliJ IDEA.