Google+
Maven
English
Deutsch

Maven ist ein Build-System für komplexe Java-Projekte.

Inhalt#

Maven Installation#

Die Version 3.0.3 verwendet die Java URLConnection, ab Version wird wieder Apache URL Client verwendet, der Probleme mit NTLM hat.

Es empfehlen sich folgende Variablen:

NameWert
M2_HOMEC:\Java\apache-maven-3.0.3\
MAVEN_OPTS-Xmx512M -XX:MaxPermSize=256M -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC
PATH%PATH%;%M2_HOME%/bin

Plugins#

Ant als Plugin#

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-antrun-plugin</artifactId>
				<version>1.7</version>
				<executions>
					<execution>
						<id>compile</id>
						<phase>compile</phase>
						<goals>
							<goal>run</goal>
						</goals>
						<configuration>
							<target>
								<echo message="${os.family}"/>
								<echo message="${os.arch}"/>
							</target>
						</configuration>
					</execution>
				</executions>
			</plugin>

Exec plugin#

		<pluginRepository>
			<id>codehaus snapshot repository</id>
			<url>http://snapshots.repository.codehaus.org/</url>
			<releases>
				<enabled>true</enabled>
			</releases>
		</pluginRepository>
                ...
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>exec-maven-plugin</artifactId>
				<executions>
					<execution>
						<goals>
							<goal>exec</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<executable>${env.GLASSFISH_HOME}/bin/asadmin</executable>
					<arguments>
						<argument>deploy</argument>
						<argument>target/test.war</argument>
					</arguments>
				</configuration>
			</plugin>
			
mvn exec:exec

Manual ant task#

	<profiles>
		<profile>
			<id>echo</id>
			<activation>
				<property>
					<name>command</name>
					<value>deploy</value>
				</property>
			</activation>
			<build>
				<defaultGoal>antrun:run</defaultGoal>
				<plugins>
					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-antrun-plugin</artifactId>
						<version>1.3</version>
						<configuration>
							<tasks>
							    <echo>Hello World!</echo>
							</tasks>
						</configuration>
					</plugin>
				</plugins>
			</build>
		</profile>
	</profiles>
	
mvn -Dcommand=echo

Javadoc Plugin#

Das Javadoc-JAR kann mit javadoc:attach-javadocs generiert werden.

Seit Java 8 gibt es Compilierfehler, die mit einer Configuration behoben werden können:

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-javadoc-plugin</artifactId>
	<version>2.9.1</version>
	<configuration>
		<additionalparam>-Xdoclint:none</additionalparam>
	</configuration>
</plugin>

Artifact manuell installieren#

mvn install:install-file -DgroupId=com.intersult -DartifactId=com.intersult.skin -Dversion=1.0-SNAPSHOT -DgeneratePom=true -Dfile=com.intersult.skin-1.0-SNAPSHOT.jar -Dpackaging=jar

Zusätzlich kann mit -Dsources=<file> und -Djavadoc=<file> die Sourcen und Javadocs installiert werden.

Eigenes Plugin#

Maven-Projekt das ein Artifakt zum Verwenden als Plugin erzeugt:
<project>
    ...
    <packaging>maven-plugin</packaging>
    ...
    <dependencies>
	<dependency>
		<groupId>org.apache.maven</groupId>
		<artifactId>maven-plugin-api</artifactId>
		<version>2.0</version>
	</dependency>
	<dependency>
		<groupId>org.apache.maven</groupId>
		<artifactId>maven-project</artifactId>
		<version>2.0</version>
	</dependency>
	
	<dependency>
		<groupId>org.sonatype.plexus</groupId>
		<artifactId>plexus-build-api</artifactId>
		<version>0.0.7</version>
	</dependency>
	<dependency>
	    <groupId>org.codehaus.plexus</groupId>
	    <artifactId>plexus-utils</artifactId>
	    <version>1.5.8</version>
	</dependency>
	...
    </dependencies>
    ...
</project>

Anlegen eines sogenannten Mojos (Maven-Pojo). Parameter können statisch mit defaults, aus Maven-Parametern durch Expressions oder aus der Plugin-Konfiguration injeziert werden.

/**
 * @goal encode
 * @phase generate-resources
 */
public class EncodingMojo extends AbstractMojo {
        /*
	 * @parameter default-value="src/main/resources"
	 */
	protected File src;
	
	/**
	 * @parameter expression="${project}"
	 * @readonly
	 */
	protected MavenProject project;
	
	/**
	 * @parameter
	 * @required
	 */
	protected Resource resource;
	
	/** @component */
	private BuildContext buildContext;

	@Override
	public void execute() throws MojoExecutionException, MojoFailureException {
	    ...
	}
        ...
}

Bei Verwendung in Eclipse ab Indigo wird das Maven-Plugin von Eclipse selbst geliefert (M2E). Dies erfordert eine erweiterte Konfiguration des Plugins, da es sonst zu Fehlern im Lifecycle kommt. Dazu wird eine Datei angelegt /<project>/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml

<?xml version="1.0" encoding="UTF-8"?>
<lifecycleMappingMetadata>
	<pluginExecutions>
		<pluginExecution>
			<pluginExecutionFilter>
				<goals>
					<goal>generate-schema</goal>
				</goals>
			</pluginExecutionFilter>
			<action>
				<execute>
					<runOnIncremental>false</runOnIncremental>
					<runOnConfiguration>true</runOnConfiguration>
				</execute>
			</action>
		</pluginExecution>
	</pluginExecutions>
</lifecycleMappingMetadata>

Ausführung unterbinden#

Möchte man zum Beispiel bei einem Projekttyp WAR unterbinden, dass das Ausführen des maven-war-plugins unterbunden wird, kann man die Phase none verwenden:
<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-war-plugin</artifactId>
	<version>2.4</version>
	<executions>
		<execution>
			<id>default-war</id>
			<phase>none</phase>
		</execution>
	</executions>
</plugin>

Artifact deployen#

mvn deploy:deploy-file -DgroupId=com.intersult -DartifactId=com.intersult.skin -Dversion=1.0 -Dpackaging=jar -Dfile=target/com.intersult.skin-1.0-SNAPSHOT.jar -Durl=svn:https://intersult.com/svn/public/maven -DrepositoryId=intersult-repo

Falls ein spezieller Wagon verwendet werden soll (Transportschicht für das Protocol-Handling), kann dieser und die Dependencies in <maven-home>/lib abgelegt werden (z.B. maven-svn-wagon-1.4.jar, svnkit-1.3.5.jar). Diese befinden sich im lokalen Repository, weil Maven diese Wagons sowieso zum Download benutzt.

Beim deployen kann -Dsources=<file> und -Djavadoc=<file> nicht verwendet werden, die Files müssen getrennt hochgeladen werden mit -Dpackaging=java-source und -DgeneratePom=false

Application Server#

Glassfish deployen#

Achtung: Die Intersult hat das Maven Glassfish Plugin erweitert. Command line:
mvn glassfish:deploy
Plugin config:
<plugin>
	<groupId>org.glassfish.maven.plugin</groupId>
	<artifactId>maven-glassfish-plugin</artifactId>
	<version>2.1</version>
	<configuration>
		<domain>
			<name>domain1</name>
			<adminPort>4848</adminPort>
		</domain>
		<glassfishDirectory>${env.GLASSFISH_HOME}</glassfishDirectory>
		<user>admin</user>
		<adminPassword>adminadmin</adminPassword>
		<echo>true</echo>
	</configuration>
</plugin>

JBoss deployen#

Command line:
mvn jboss:redeploy
Plugin config:
<plugin>
	<groupId>org.codehaus.mojo</groupId>
	<artifactId>jboss-maven-plugin</artifactId>
	<version>1.4</version>
	<configuration>
		<hostName>localhost</hostName>
		<port>8080</port>
		<serverName>default</serverName>
		<fileNames>
			<fileName>${project.build.directory}/${project.build.finalName}.${project.packaging}</fileName>
		</fileNames>
	</configuration>
</plugin>

Nexus Artifact Repsitory#

Die Artifacts werden in einem Repository abgelegt. Dabei sind viele Systeme dafür zu gebrauchen, das Dateisystem per file-URL, ein Web-Server per http-URL, ein SVN-Server per svn-URL und so weiter. Darüber hinaus gibt es explizite Repositories, der bekannteste darunter ist der Nexus. Dieser bietet sich auch an, weil er vom Hersteller von Maven kommt.

Logfile anzeigen#

Grundsätzlich kann das Logfile über die Oberfläche unter Administration -> System Files -> nexus.log angezeigt werden. Eine Alternative ist ein direkter Link http://localhost/nexus/service/local/logs/nexus.log.

Debugging#

Maven Prozesse können debuggt werden, indem statt mvn der Befehl mvnDebug verwendet wird. Maven wartet dann auf Port 8000 auf ein Debugger Attachement.

Tests können so nicht debuggt werden, da für sie eine eigene VM erzeugt wird. Dies kann verhindert werden, indem das Surefire-Plugin konfiguriert wird:

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>2.10</version>
				<configuration>
 					<forkMode>never</forkMode>
				</configuration>
			</plugin>

Allerdings können sich dann Probleme mit dem Classpath ergeben.

Profile unter Hudson aktivieren#

   <profile>
     <id>hudson</id>
     <activation>
         <property>
             <name>BUILD_NUMBER</name>
         </property>
     </activation>
     ...
   </profile>

Authentication#

Wird auf ein Repository zugegriffen, bei dem Authentifiziert werden muss (z.B. HTTPS, Username, Passwort), kann dies in den settings.xml abgelegt werden. Damit tauchen keine Passwörter in den eingecheckten pom.xml-Dateien auf:
	<servers>
		<server>
			<id>intersult-repo</id>
			<username>username</username>
			<password>passwort</password>
		</server>
	</servers>

OS Profile#

	<profiles>
		<profile>
			<id>win-32bit</id>
			<activation>
				<os>
					<family>windows</family>
					<arch>x86</arch>
				</os>
			</activation>
			<properties>
				<some.classifier>win-32bit</some.classifier>
			</properties>
		</profile>
		<profile>
			<id>win-64bit</id>
			<activation>
				<os>
					<family>windows</family>
					<arch>amd64</arch>
				</os>
			</activation>
			<properties>
				<some.classifier>win-64bit</some.classifier>
			</properties>
		</profile>
            </profiles>

Proxy#

Für normale Operationen mit Maven reicht ein Proxy-Eintrag im %USERPROFILE%\.m2\settings.xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
	<localRepository/>
	<interactiveMode/>
	<usePluginRegistry/>
	<offline/>
	<pluginGroups/>
	<servers/>
	<mirrors/>
	<proxies>
		<proxy>
			<id>[id]</id>
			<active>true</active>
			<protocol>http</protocol>
			<host>[host]</host>
			<port>[port]</port>
			<nonProxyHosts>127.0.0.*|localhost|10.1.*</nonProxyHosts>
		</proxy>
	</proxies>
	<profiles/>
	<activeProfiles/>
</settings>

Subversion#

Beim Verwenden von Subversion-Operationen, zum Beispiel deploy:deploy-file ist zusätzlich das SVN-Proxy im Subversion unter %APPDATA%\Subversion\servers anzugeben:
[global]
http-proxy-host = [host]
http-proxy-port = [port]
http-proxy-exceptions = 127.0.0.*, localhost, 10.1.*

NTLM Authentifizierung#

Seit Maven 3.0.4 wird mit dem Apache-HTTP-Client gearbeitet, der keine transparente NTLM-Authentifierung unter Windows beherrscht. Um dies wieder möglich zu machen, kann man den HTTP-Lightweight-Wagon ins ext-Verzeichnis der Maven-Installation kopieren.

Eigener Wagon#

Man kann sehr einfach eigene Wagons für den Transport schreiben, am besten man nimmt sich org.apache.maven.wagon:wagon-http-lightweight als Vorlage, bei Maven 2.2.1 ist dies Version 1.0.

Die eigentlich Wagons sind mit einer Annotation versehen:

/**
 * IntersultHttpWagon
 * 
 * @plexus.component role="org.apache.maven.wagon.Wagon" role-hint="http-intersult"
 *                   instantiation-strategy="per-lookup"
 */
public class IntersultHttpWagon extends StreamWagon {
    ...

Will man die Wagons verwenden, werden die im Build-Prozess des Target-Projecte einfach als Build-Extension eingebunden.

	<build>
		<extensions>
			<extension>
				<groupId>com.intersult</groupId>
				<artifactId>wagon-http-intersult</artifactId>
				<version>1.0-SNAPSHOT</version>
			</extension>
		</extensions>
            ...

Das Aktivieren als Default-Wagon für ein Protokoll (also HTTP, HTTPS etc.) erfolgt durch das Build-Kommando:

    mvn -Dmaven.wagon.provider.http=intersult install

Oder permanent in der settings.xml für bestimmte Server:

		<server>
			<id>intersult-repo</id>
			<configuration>
				<wagonProvider>intersult</wagonProvider>
			</configuration>
		</server>

Grundsätzlich hat Maven eine Fallback-Strategie, wenn der Wagon (noch) nicht geladen werden kann. Dies tritt insbesondere während des Bootstrap von Maven auf. Maven führt in diesem Fall generell einen Fallback auf die Standard-Wagons aus. Allerdings funktioniert das nicht, wenn der zu ladende Wagon sich in einem Repository befindet, für das genau dieser Wagon benötigt wird.

Beim Build des Wagons muss der Build-Descriptor mit dem plexus-maven-plugin erzeugt werden:

	<plugin>
		<groupId>org.codehaus.plexus</groupId>
		<artifactId>plexus-maven-plugin</artifactId>
		<version>1.3.8</version>
		<executions>
			<execution>
				<id>generate</id>
				<phase>prepare-package</phase>
				<goals>
					<goal>descriptor</goal>
				</goals>
			</execution>
		</executions>
	</plugin>

Phase: Die Angabe des Phase-Parameters prepare-package dient dazu, Probleme mit M2E-Plugin unter Eclipse zu lösen, da das M2E bei der Phase generate-sources einen Descriptor verlangt. Das plexus-maven-plugin der Version 1.3.8 ist noch nicht M2E-kompatibel.

Bemerkung: Möglicher Weise gibt es auch eine Lösung mit Packaging maven-plugin, allerdings ist mir nicht bekannt wie man die Fehlermeldung weg bekommt dass keine Mojos gefunden wurden und statt dessen die Descriptoren für die Wagons generiert werden.

HTTP-Connections#

Bei den unterschiedlichen Maven-Versionen wurde sehr viel an der HTTP-Verbindung verändert. Anfangs verwendete Maven den Apache HttpClient, bis Version 3.0.3 wurde dann Java URLConnection verwendet.

Version 3.0.4 verwendet nun wieder HttpClient 4.1.2. Diese Version arbeitet generell wieder besser als die Versionen Maven 2.*, allerdings geht kein transparentes NTML mehr (Windows-Authentifizierung). In diesem Fall ist 3.0.3 zu verwenden.

Eclipse Classpath Fehler#

Bei Eclipse tritt momentan noch häufiger auf: "Updating Maven Project". Unsupported IClasspathEntry kind=4. Lösung:
  • Disable Maven Nature: Kontextmenü auf dem Projekt -> Maven -> Disable Maven Nature
  • Clean: Aus Kommandozeile mvn eclipse:clean
  • Enable Maven Nature: Kontextmenü -> Configure -> Convert to Maven Project

Logging#

Bei der Version 3.0.4.X (RC3?) kommt es zu einem exzessiven Logging von Cookie-Problemen. Auch sonst kann eine Konfiguration des Loggings nützlich sein. Dazu legt man die Datei %HOME%/.m2/logging.properties an:
.level = INFO
handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.ConsoleHandler.level = ALL

Mehr dazu bei https://support.sonatype.com/entries/23656571-Configuring-Maven-HTTP-Wagon-Detailed-Logging

Shading#

Mit Maven ist es möglich, Abhängigkeiten in ein produziertes JAR mit aufzunehmen, also umzupacken. Dies wird als Shading bezeichnet. Grundsätzlich ist dies keine empfohlene Vorgehensweise, die Abhängigkeiten sollten nach aller Möglichkeit in eigenen JAR-Dateien bleiben.

In manchen Fällen ist es allerdings unvermeidbar, dafür gibt es das Shading-Plugin. Die Anwendung ist sehr einfach:

	<plugin>
		<groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-shade-plugin</artifactId>
		<version>2.0</version>
		<executions>
			<execution>
				<phase>package</phase>
				<goals>
					<goal>shade</goal>
				</goals>
			</execution>
		</executions>
	</plugin>

Build Number#

Bisher gab es das buildnumber-maven-plugin mit dem das aktuelle Build Date als Variable abgefragt werden kann. Ab Maven 3 ist diese Variable als maven.build.timestamp fest eingebaut. Das Format kann über das Property maven.build.timestamp.format nochmal verändert werden, Default ist yyMMdd_HHmm.

Neuen Anhang hinzufügen

Du bist nicht autorisiert, Anhänge zu dieser Seite hochzuladen.
« Diese Seite (Version-48) wurde zuletzt am 28-Jul-2015 08:43 von Dieter Käppel geändert.