Maven: Životní cyklus, fáze a cíle

Základem Mavenu je standardizovaná posloupnost událostí, která zajišťuje, že každý projekt projde stejnými kroky – od kompilace až po distribuci.

1. Životní cyklus (Lifecycle)

Životní cyklus je pevně definovaná sekvence fází. Stanovuje „co“ se bude dít.

Maven má tři standardní, neměnné životní cykly:

Číst dál

Co je Apache Maven?

Apache Maven je nástroj pro správu projektů a automatizaci sestavování (build process), používaný převážně pro projekty v Javě. Jeho hlavním cílem je:

  1. Standardizovat sestavování: Zajistit, aby se každý projekt sestavoval stejným, konzistentním způsobem.
  2. Zjednodušit správu závislostí: Automaticky stahovat a spravovat externí knihovny.
  3. Použít konvence: Řídí se principem konvence nad konfigurací (convention over configuration), což znamená, že projekty mají mít standardní strukturu, čímž se minimalizuje složitá konfigurace.

Základní názvosloví Mavenu

Zde jsou klíčové pojmy, které definují, jak Maven funguje:

Číst dál

Zobrazení effective pom v Idea IDE

V Idea IDE lze efektivní pom zobrazit následovně: Kliknout pravým tlačítkem na pom.xml v projektu -> Maven -> Show Effective POM.

Vysvětlení pojmů

Super pom
Všechny maven projekty dědí z super pomu, který obsahuje defaultní hodnoty. Super pom je rodič všech pom souborů.

Simple pom
Pom, který je ve vašem projektu. V případě jednoduchého projektu není třeba definovat téměr vůbec nic, vše potřebné se vezme ze super pomu.

Effective pom
Spojení super a simple (projektového) pomu.


Zdroje:

Maven a scope test

Maven má rozsahy (scope), kterými je možno ovlivnit, která závislosti se bude používat v které fázi maven buildu. Rozsah test znamená, že dané závislosti (knihovny) budou k dispozici během testovací fáze, ale jinak ne.
Jednoduchý příklad ukážu na knihovně TestNG, která se používá pro testování. Závislost v pom.xml vypadá následovně:

<dependency>
	<groupId>org.testng</groupId>
	<artifactId>testng</artifactId>
	<version>6.11</version>
	<scope>test</scope>
</dependency>

Pokud budeme mít třídu AppTest v balíčku src/test/java a v ní tento test, který používá knihovnu TestNG:

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotEquals;

import org.testng.annotations.Test;

public class AppTest {
	@Test
	public void test() {
		assertNotEquals("A", "B");
		assertEquals(10, 10);
	}
}

při spuštění buildu aplikace pomocí mavenu (mvn test, z Eclipse IDE Run As -> Maven test) proběhne vše v pořádku (knihovna TestNG je k dipozici, kód se zkompiluje a proběhne).

Číst dál

Nastavení verze závisloti v maven properties

Závislosti v souboru pom.xml jsou uváděny včetně verze <version></version>.

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>

Napřiklad při použití Spring frameworku je pravděpodobné, že závislostí bude řada a velké množství z nich bude používat stejnou verzi. Je pak vhodné mít configuraci verzí na jednom místě a pokud mají závislosti stejnou verzi, tak je sdílet. Toho lze docílit pomocí elementu <properties></properties> v pom.xml a použití ${...}. V následujícím příkladu budu mít tři závislosti a z toho dvě budou mít stejnou verzi.

<properties>
	<spring-version>4.3.5.RELEASE</spring-version>
	<spring-batch-version>3.0.7.RELEASE</spring-batch-version>
</properties>

<dependencies>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
		<version>${spring-version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>${spring-version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework.batch</groupId>
		<artifactId>spring-batch-core</artifactId>
		<version>${spring-batch-version}</version>
	</dependency>
</dependencies>

Do elementu <properties></properties> se vloží element s verzí a ve <version></version> se pak na něj odkazuje pomocí názvu uvedeného v ${...}.

OutOfMemoryError při testech

V případě, že dostanete následující chybu při Maven buildu (mvn clean install)

Tests run: 226, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 316.116 sec - in TestSuite
Exception in thread "main" Exception in thread "Thread-0" Picked up JAVA_TOOL_OPTIONS: -Djava.vendor="Sun Microsystems Inc."
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Thread-0"

Results :

Tests run: 226, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] CEB UMA Parent ..................................... SUCCESS [ 5.639 s]
[INFO] CEB UMA API ........................................ SUCCESS [ 15.656 s]
[INFO] CEB UMA Impl ....................................... FAILURE [05:37 min]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 05:59 min
[INFO] Finished at: 2016-03-29T15:08:52+02:00
[INFO] Final Memory: 43M/272M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.16:test (default-test) on project project_name: Execution de fault-test of goal org.apache.maven.plugins:maven-surefire-plugin:2.16:test failed: The forked VM terminated without saying properly goodbye . VM crash or System.exit called ?

Zkuste změnit nastavení paměti určené pro surefire plugin.

<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-surefire-plugin</artifactId>
 <configuration>
 <argLine>-Xmx4096m</argLine>
 </configuration>
</plugin>

Surefire plugin se používá pro spouštění testů v lifecycle default, fázi test a výše uvedená chyba může signalizovat nedostatek paměti. Volba -Xmx určuje maximální velikost paměti (maximální velikost Java heap). Java heap (halda) je paměť určená pro Java objekty.

Základní názvosloví v Mavenu

Build life cycle
Build life cycle je přesně definovaná posloupnost fází. Build life cycle se skládá z několika úseků, kroků -> ty se nazývají fáze (phases). Maven má tři build life cycles: clean (smazání dočasných souborů, default (sestavení, zabalení a nasazení projektu) a složky target) a site.

Phase
Phase je část, která se provádí v rámci build life cyklu. Fáze může obsahovat jeden nebo více úkolů (goals) -> fáze je spojena s jedním nebo více cíli (goals).

Plugin
Plugin obsahuje jeden nebo více cílů (goals). Jednoduše řečeno je plugin seznam jednotlivých cílů. Programátorsky se jedná o projekt, který obsahuje jednotlivé třídy, ve kterých je definována funkcionalita určitého cíle (goal).

Goal vs MOJO
Mojo je zkratka (Maven Old Java Object). Je to slovní hříčka z POJO (Plain Old Java Object). Mojo je Java třída implementující goal. Plugin je Java projekt obsahující jeden či více cílů (goal) = jeden či více Mojo.

Build life cycle (maven má tři: clean, default, site) se skládá z fází (phases). Během každé fáze se provádí různé úkoly (goals). Cíle jsou definovány v pluginech a proto, aby se v určité fázi provedli, jsou tyto cíle (goals) přiřazeny jednotlivým fázím. Jinak řečeno, jednotlivým fázím jsou přiřazeny cíle (goals) a tyto cíle (goals) jsou definovány v pluginech. Programově každý goal představuje mojo a plugin je seznamem jednotlivých cílů (goals).


Zdroje:

Archetyp quickstart

Maven archetype je předdefinovaný vzor (forma, šablona) projektu a může být použit pro vygenerování nového projektu. Projekty vygenerované podle jednoho archetypu mají stejnou strukturu. V Mavenu je celá řada připravených šablon (archetypů). Jednou z nich je archetyp quickstart.

Parametry
groupId: vitfo.cz
artifactId: quickstart_project
version: 1.0-SNAPSHOT

Vygenerovaná struktura

quickstart_project
│   pom.xml
│
└───src
    ├───main
    │   └───java
    │       └───cz
    │           └───vitfo
    │                   App.java
    │
    └───test
        └───java
            └───cz
                └───vitfo
                        AppTest.java

Minimální pom.xml

Minimální pom.xml musí být uvozen tagem <project> a musí obsahovat tagy <modelVersion>, <groupId>, <artifactId> a <version>.

<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/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>cz.vitfo</groupId>
    <artifactId>projekt</artifactId>
    <version>0.0.1-SNAPSHOT</version>

</project>

<modelVersion>4.0.0</modelVersion>
Určuje verzi modelu pom. Aktuálně je podporována pouze verze 4.0.0. Tento tag je povinný.

<groupId>cz.vitfo</groupId>
Identifikuje firmu, skupinu, nebo vývojáře, který tento projekt vytvořil. Nejčastěji se používá se url (psaná od domény nejvyšího řádu), kterou má daná firma, skupina, vývojář zaregistrovánu, protože se jedná o jedinečný identifikátor.

<artifactId>projekt</artifactId>
Identifikuje projekt. Musí být jedinečný v rámci groupId. Společnost (vývojář) mohou vytvořit více projektů (stejné groupId), ale tyto projekty musí mít jedinečné artifactId.

<version>0.0.1-SNAPSHOT</version>
Určuje verzi projektu. Slovo SNAPSHOT se používá v případě, že projekt je ve vývoji.

Tagy groupId, artifactId a version se zazývají GAV souřadnice a jednoznačně určují soubor projektu.