Maven
Sissejuhatus
Maven on Java ökosüsteemis kõige laialdasemalt kasutatav ehitusinstrument. See järgib "convention over configuration" põhimõtet ehk kui struktureerid oma projekti nii, nagu Maven seda eeldab, töötab enamik asju minimaalse seadistusega.
Kogu projekti konfiguratsioon asub ühes failis: pom.xml (Project Object Model).
See fail määrab projekti identiteedi, selle sõltuvused,
kasutatava Java versiooni ning kõik ehituseks vajalikud pluginad.
Projekti koordinaadid
Iga Maveni projekt on tuvastatav kolme koordinaadiga:
<groupId>ee.taltech.iti0202</groupId>
<artifactId>buildtools</artifactId>
<version>1.0</version>
- groupId — sinu organisatsioon või domeen pöörd-DNS-notatsioonis
- artifactId — selle konkreetse projekti või mooduli nimi
- version — sinu projekti praegune versioon
Neid samu koordinaate kasutatakse ka sõltuvuste tuvastamiseks.
Kui kasutad sõltuvusena näiteks Gsoni versiooni 2.10.1,
viitad selle groupId-le, artifactId-le ja versioonile Maven Centralis.
Minimaalse pom.xml faili näide
Tutvuge jägneva minimaalse pom.xml failiga Java 17 projekti jaoks,
mis kasutab Gson-it sõltuvusena:
<?xml version="1.0" encoding="UTF-8"?>
<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>ee.taltech.iti0202</groupId>
<artifactId>buildtools</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
<properties> plokk määrab Java versiooni ja failikodeeringu.
<dependencies> plokk loetleb, mida projekt vajab.
Sellest piisab, et Maven saaks projekti kompileerida, testida ja pakendada.
Sõltuvused ja nende skoobid
Kui lisad projekti sõltuvuse, siis on võimalik määrata selle ulatust (scope), mis määrab, millal see on saadaval:
| Skoop | Saaval kompileerimise ajal | Saadaval testimise ajal | Pakendatud JAR failis | Example |
|---|---|---|---|---|
compile (vaikimisi) | Jah | Jah | Jah | Gson |
test | Ei | Jah | Ei | JUnit |
provided | Jah | Jah | Ei | Servlet API (provided by the server) |
runtime | Ei | Jah | Jah | JDBC draiverid |
Kõige olulisem eristus on compile ja test vahel.
JUnit deklareeritakse <scope>test</scope>-iga, kuna seda on vaja ainult testide käivitamiseks.
See ei tohiks sattuda lõplikusse JAR-faili.
Kui eemaldad JUnit-ilt <scope>test</scope>, muutub see compile-ulatusega sõltuvuseks.
Projekt küll ehitub endiselt, kuid JUniti klassid pakitakse nüüd JAR faili kaasa,
mis on ebavajalik ja ebasoovitav.
Ehitusprotsessi elutsükkel
Maven organiseerib ehitusprotsessi erinevates etappideks. Iga etapp viib läbi mingi kindla tegevuse. Mõne kindla etappi käivitamisel käivitatakse ka kõik sellele eelnevad.
Need etapid on järgnevad:
validate -> compile -> test -> package -> verify -> install -> deploy
Praktikas kasutatakse kõige rohkem:
| Käsklus | Kirjeldus |
|---|---|
mvn compile | Kompileerib src/main/java sisu target/classes kataloogi |
mvn test | Kompileerib + käivitab testid src/test/java kataloogist |
mvn package | Kompileerib + testib + loob JAR faili target/ kataloogi |
mvn clean | Kustutab target/ kataloogi sisu tervenisti |
mvn clean package | Kustutab target/ kataloogi sisu ning käivitab terve ehitusprotsessi |
target/ kataloog on koht, kuhu Maven paigutab kogu ehitusprotsessi väljundi.
Sinna hulka kuuluvad: kompileeritud klassid, testitulemused ja lõpliku JAR-faili.
Käsk mvn clean kustutab selle täielikult, tagades järgmisel korral puhta ehitusprotsessi.
Lokaalne repositoorium
Sõltuvuse esmasel avastamisel tõmbab Maven selle automaastelt alla
ning asetseb selle lokaalsesse repositooriumisse, mis asub ~/.m2/repository/ kataloogis.
~/.m2/repository/
└── com/
└── google/
└── code/
└── gson/
└── gson/
└── 2.10.1/
├── gson-2.10.1.jar
└── gson-2.10.1.pom
Järgmistel kordadel kasutatakse juba vahemällu salvestatud JAR-faile ega laeta neid enam uuesti alla. See vahemälu on jagatud kõigi sinu masinas olevate Maveni projektide vahel.
Sõltuvuste puu
Päris projektidel on transitiivsed sõltuvused ehk sinu sõltuvustel on omakorda oma sõltuvused. Kogu puu nägemiseks saab kasutada järgmist käsklust:
mvn dependency:tree
See käsk näitab kõiki teeke, mille Maven lahendab, sealhulgas transitiivseid, ning milline sõltuvus need kaasa tõi. See on hädavajalik versioonikonfliktide silumisel.
Pistikprogrammid
Maveni elutsükli etappid on realiseeritud pistikprogrammide abil.
compiler pistikprogramm kompileerib koodi, surefire käivitab testid, jar pistikprogramm loob JAR-faile.
Enamik neist on vaikimisi kaasas, kuid neid saab ka eraldi seadistada:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
Tavaliselt lisatakse <plugin> plokk ainult siis, kui on vaja muuta vaikimisi käitumist,
näiteks määrata Java versioon vanema Maveni versiooni puhul või lisada koodianalüüsi tööriistu.
Millal kasutada Mavenit
Maven sobib hästi siis, kui sinu projekt vastab standardsele mudelile: teek või rakendus standardsete sõltuvuste, kompileerimise ja testimisega. Selle jäik struktuur on eelis - vähem on vaja seadistada ja vähem saab valesti minna.
Maven sobib halvemini projektidele, mis vajavad väga kohandatud build-loogikat, mitme platvormi jaoks ehitamist või olukordades, kus ehitusprotsessi kiirus on kriitiline. Sellistel juhtudel on Gradle sageli parem valik.