Maven

Maven Buch: Better Build With Maven Better Build With Maven online lesen

Erster Test, geht Maven?

mvn -version

Ein neues Projekt erzeugen

mvn archetype:create   -DgroupId=bar.foo.main -DartifactId=MyFirstMavenApplication

Oder so

mvn archetype:generate -DgroupId=bar.foo.main -DartifactId=MyFirstMavenApplication

Alternativ in Eclipse

File -> New -> Other ... -> Maven -> Maven Project

So wird das jar heißen dass man damit baut, so nennt auch Eclipse das Projekt.

artifactId

Muss weltweit eindeutig sein, kann mehrere artifactId zusammenfassen. Am besten Domain rückwärts benutzen und noch Abteilung oder Projektname anhängen

groupId

Compile

cd MyFirstMavenApplication
mvn compile

Man kann auch nur mal ausprobieren, ob es kompilieren würde

mvn test-compile

So führt man Surefire Tests für das Projekt durch

mvn test

So erstellt man ein Package

mvn package

Und so eines mit Abhängigkeiten

mvn package assembly:single

Clean

mvn clean

Eclipse Konfigurationsdateien erzeugen

mvn eclipse:eclipse

Eine Webseite über das Projekt erzeugen lassen

mvn site

Style Fehler finden (landet in checkstyle-result.xml)

mvn checkstyle:checkstyle

Liste aller verfügbaren Maven Plugins

Wie fügt man Dateien in das erzeugte jar?

Alles was unter

srcmainresources

steht wird 1:1 in das jar übernommen (also z.B. auch jars von Drittanwendungen, die dort hineinkopiert werden).

Für die Tests gilt entsprechend

srctestresources

Wie erklärt man Abhängigkeiten?

<project>
[...]
<version>1.42</version>
 <dependencyManagement>
  <dependencies>
   <dependency>
    <groupId>foo.bar</groupId>
    <artifactId>blub</artifactId>
    <version>${project.version}</version>
   </dependency>
  <dependency>
   <groupId>foo.other</groupId>
   <artifactId>X</artifactId>
   <version>1.11</version>
  </dependency>
 </dependencies>
</dependencyManagement>
[...]
</project>

Man kann aus einem pom.xml auch auf ein parent pom.xml verweisen. Dann muss das child pom.xml keinen Versionen in den Abhängigkeiten mehr einfordern, sondern die werden aus dem parent pom.xml gezogen.

Junit kann man so einbauen

<project>
 [...]
 <dependencies>
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>3.8.1</version>
   <scope>test</scope>
  </dependency>
 </dependencies>
 [...]
</project>

Hier kann man Einstellungen festlegen (z.B. Umgebungspezifische Parameter)

<user_home>/.m2/settings.xml
profiles.xml

So kann man das Projekt gleich an den Zielort kopieren lassen (deploy)

<project>
 [...]
 <distributionManagement>
  <repository>
   <id>foo</id>
   <name>My Foo Repository</name>
   <url>scp://foo.example.com/deploy</url>
  </repository>
  </distributionManagement>
 [...]
</project>

Wie fügt man 3rdparty libs hinzu? Entweder die Libs werden bereits auf http://mvnrepository.com gelistet. Dann reicht es, eine entsprechende Abhängigkeit zu benennen

<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.16</version>
</dependency>

Die jars stehen dann automatisch zur Verfügung.

Alternativ kann man auch ein lokales jar referenziere

<dependency>
  <groupId>foo</groupId>
  <artifactId>blub</artifactId>
  <version>1.2.3</version>
  <scope>system</scope>
  <systemPath>${basedir}/lib/foo-1.2.3.jar</systemPath>
</dependency>

Letzteres wird aber nicht empfohlen.

Wenn man mit Maven solche Fehler bekommt:

generics are not supported in -source 1.3
(use -source 5 or higher to enable generics)
annotations are not supported in -source 1.3
(use -source 5 or higher to enable annotations)
for-each loops are not supported in -source 1.3
(use -source 5 or higher to enable for-each loops)

Kann man so einstellen, welche Version man beim Compilieren benutzen möchte:

<project ...>
  ...
  <dependencies>
  ...
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
        </configuration>
      </plugin>
    </plugins>
  </build>

  ...
</project>

Unter Maven kann man mit org.codehaus.mojo.exec-maven-plugin den compilierten Code auch gleich ausführen:

<build>
  <plugins>
    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>2.0.2</version>
      <configuration>
        <source>1.7</source>
        <target>1.7</target>
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>exec-maven-plugin</artifactId>
      <configuration>
        <mainClass>de.tgunkel.de.java.Foo.MyMainClass</mainClass>
      </configuration>
    </plugin>
  </plugins>
</build>

Und dann

mvn exec:java

Test Enforcer

mvn compile -P enforcer --update-snapshots
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireUpperBoundDeps failed with message:
Failed while enforcing RequireUpperBoundDeps. The error(s) are [
Require upper bound dependencies error for ... paths to dependency are:

m2e

Das m2eclipse Maven Eclipse Plugin. So einfach kann man mit m2e direkt aus einem Subversion Ordner ein Eclipse Projekt erstellen lassen https://www.tgunkel.de/it/software/doc/java_files/m2eMavenSVNImport"maven m2e Subversion import"

Maven erzeugt eine Eclipse Konfigurationsdatei, in der keine absoluten Pfade stehen. Das ist sehr praktisch, weil man die dann einchecken kann und andere die auch benutzen können. Falls das erst nicht mal nicht funktioniert mit dieser Fehlermeldung

Unbound Classpath Variable M2_REPO

In Eclipse Unter Preferences - Java - Classpath Variables die Variable M2_REPO anlegen und auf den Maven Repository Eintrag zeigen lassen

Eclipse Unbound Classpath Variable M2_REPO

Geht wohl auch via

mvn -Declipse.workspace=/home/foo/HERE_IS_MY_ECLIPSE_WORKSPACE eclipse:add-maven-repo

Manchmal gibt es Abhängigkeit nicht auf den Maven Server (z.B. aus Lizengründen). Dann kann man die auch manuell hinzufügen. Hier ein Beispiel für den Oracle JDBC Treiber. Erst mal die Abhängigkeit normal definieren

<dependency>
  <groupId>com.oracle</groupId>
  <artifactId>ojdbc16</artifactId>
  <version>11.2.0.2.0</version>
</dependency>

Dann die Datei "ojdbc6.jar" runterladen und in die lokale Maven Installation hinzufügen

mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc16 -Dversion=11.2.0.2.0 -Dpackaging=jar -Dfile=ojdbc6.jar -DgeneratePom=true

Maven über einen Proxy

Maven so einstellen, dass es ein Proxy benutzt wird ~/.m2/settings.xml

<settings>
  <proxies>
    <proxy>
      <active>true</active>
      <protocol>http</protocol>
      <host>my.proxy.foo.bar</host>
      <port>8080</port>
      <!--
          <username>your-username</username>
          <password>your-password</password>
      -->
    </proxy>
  </proxies>
</settings>

Proxy für m2e

Wenn man m2e benutzen möchte und hinter einem Proxy sitzt gibt es mindestens 4 relevante Konfigurationen:

  • Den Proxy in Eclipse unter
Preferences - General - Network Connections

einrichten

  • Den Proxy für Subclipse unter
C:UsersUSERIDAppDataRoamingSubversion

einstellen

  • Den Proxy für m2e unter
C:UsersUSERID.m2settings.xml

einstellen

Vergisst man den Proxy für Subclipse kann man kein Maven Projekt über eine SVN URL importieren, vergisst man den Proxy für m2e gibt es folgende Fehlermeldung:

Project build error: Non-resolvable parent POM for

Release a new version

Your current code is on a SNAPSHOT version, e.g. 0.5.1-SNAPSHOT. Now you want to make a release so other people can depend on a specific version.

You have to chose a version number for the release, semantic versions are MAJOR.MINOR.PATCH, you increment

  • MAJOR version when you make incompatible API changes,
  • MINOR version when you add functionality in a backwards-compatible manner, and
  • PATCH version when you make backwards-compatible bug fixes.

This will make that release, and also set a tag in the scm

mvn release:prepare

This will upload the release

mvn release:perform

After this others have to change their dependencies in their pom.xml.

In order to be able to upload jar in the nexus you will need to configure your credentials in ~/.m2/settings.xml

<settings>
...

  <servers>
    <server>
      <id>nexus-releases</id>
      <username>foo</username>
      <password>bar</password>
    </server>
    <server>
      <id>nexus-snapshots</id>
      <username>foo</username>
      <password>bar</password>
    </server>
  </servers>

...  
</settings>

Create Docker containers from within Maven

This contains a nice overview with different options https://itnext.io/using-maven-to-build-docker-73c83e626025

  • The Maven exec Plugin
  • Spotify Maven Docker Plugin
  • The Google JIB Plugin

There is also fabric8io/docker-maven-plugin which supports building multiple / different images