Liigu peamise sisu juurde

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:

SkoopSaaval kompileerimise ajalSaadaval testimise ajalPakendatud JAR failisExample
compile (vaikimisi)JahJahJahGson
testEiJahEiJUnit
providedJahJahEiServlet API (provided by the server)
runtimeEiJahJahJDBC 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.

hoiatus

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äsklusKirjeldus
mvn compileKompileerib src/main/java sisu target/classes kataloogi
mvn testKompileerib + käivitab testid src/test/java kataloogist
mvn packageKompileerib + testib + loob JAR faili target/ kataloogi
mvn cleanKustutab target/ kataloogi sisu tervenisti
mvn clean packageKustutab 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.