Konačno sam razjasnio Maven, alatku za izgradnju projekata~
Konačno sam razjasnio Maven, alatku za izgradnju projekata~
Danas ću vam predstaviti jedan alat za izgradnju projekata — Maven. Ne samo da nam može pomoći da automatizujemo izgradnju, već i apstrahuje proces izgradnje i obezbeđuje implementaciju zadataka izgradnje; višeplatformski je i nudi dosledan interfejs za rad, što je sve dovoljno da ga učini odličnim i popularnim alatom za izgradnju. Od sada pa nadalje, nećete više morati da brinete da li ćete projekat uništiti.
Da rezimiram, prednosti Maven-a se uglavnom ogledaju u sledeće 3 tačke:
- Upravljanje zavisnostima: Maven nam pomaže da rešimo problem upravljanja softverskim zavisnostima, tako da više nije potrebno slati veliki broj jar paketa i ručno unositi biblioteke trećih strana.
- Standardna struktura direktorijuma: standardna struktura direktorijuma koju Maven propisuje pomaže u standardizaciji izgradnje projekta. Konfiguracijom profila mogu se takođe čitati različiti konfiguracioni fajlovi u zavisnosti od okruženja (razvojno, testno, produkciono).
- Laka integracija: može se integrisati u IDE radi jednostavnijeg korišćenja.
Jedan: Instalacija Maven-a
Pošto je JDK preduslov za instalaciju Maven-a, prvo proverite pomoću komande java -version da li je JDK već instaliran:

Lično koristim macOS, pa postoje dva načina instalacije: prvi je preuzimanje sa zvaničnog sajta i ručna instalacija; drugi je korišćenje brew-a za instalaciju jednom komandom.
Prvo ćemo opisati preuzimanje sa zvaničnog sajta i ručnu instalaciju, što se takođe primenjuje na Windows sistem — za razlike pogledajte zvanični Maven vodič za instalaciju:
1) Preuzimanje sa zvaničnog sajta i ručna instalacija
Prvi korak, idite na zvanični sajt da preuzmete Maven instalacioni paket:
Zvanična adresa: http://maven.apache.org/download.cgi

Mnogo početnika ne zna koji paket da odabere prilikom preuzimanja sa zvaničnog sajta, pa ću ovde dati kratko objašnjenje.
- bin (binary) označava binarne class fajlove nastale kompilacijom Java izvornih fajlova, dok src (source) označava Java izvorne fajlove.
- U većini slučajeva je dovoljno izabrati bin fajl za instalaciju; ako želite sami da kompajlirate, možete izabrati src verziju.
- tar.gz format kompresije je namenjen Unix operativnim sistemima, dok je zip namenjen Windows operativnim sistemima; ali to nije apsolutno pravilo.
Drugi korak, raspakujte preuzeti instalacioni paket i kopirajte tu putanju:

- bin direktorijum: sadrži sve skripte potrebne za rad Maven-a, koje služe za konfiguraciju Java komandi, pripremu okruženja za izvršavanje, a zatim i za izvršavanje Java komandi.
- boot direktorijum: sadrži samo jedan fajl plexus-classworlds-xxx-jar, koji predstavlja okvir za učitavanje klasa (classloader) — zamenu za podrazumevani Java classloader, sa bogatijom sintaksom za konfiguraciju. Maven koristi njega da učita svoje sopstvene biblioteke klasa.
- conf direktorijum: sadrži jedan veoma važan fajl — settings.xml. Možete direktno izmeniti ovaj fajl kako biste globalno prilagodili ponašanje Maven-a; takođe možete kopirati ovaj fajl u direktorijum
~/.m2/(~ označava korisnički direktorijum) i izmeniti ga kako biste prilagodili ponašanje Maven-a na nivou korisnika. - lib direktorijum: sadrži Java biblioteke klasa potrebne za rad Maven-a, uključujući i zavisnosti od biblioteka trećih strana, kao što je slf4j-api.jar.

Treći korak, konfiguracija promenljivih okruženja
Otvorite terminal, unesite komandu vim ~/.bash_profile da otvorite fajl bash_profile:

Fajl bash_profile služi za konfiguraciju promenljivih okruženja i pokretanje programa — detaljan opis možete pogledati ovde:
U fajl dodajte komande za postavljanje promenljivih okruženja:
export M2_HOME=/Users/maweiqing/cmower/save/apache-maven-3.8.3
export PATH=${PATH}:${M2_HOME}/bin
Nakon snimanja i izlaska, možete izvršiti source ~/.bash_profile da primenite konfiguraciju:

Četvrti korak, provera da li je konfiguracija primenjena
Unesite komandu mvn -v. Ako se pojavi sledeći izlaz, konfiguracija je uspešna:

Ako nije primenjena, pokušajte da otvorite novi prozor terminala i ponovo izvršite komandu mvn -v.
2) Instalacija jednom komandom pomoću brew-a
Prvi korak, koristite komandu brew install maven za instalaciju jednim klikom, uz automatsko konfigurisanje promenljivih okruženja.
Drugi korak, koristite komandu mvn -v da proverite verziju.
3) jenv za upravljanje verzijama JDK-a i Maven-a
Na mom računaru se jednom pojavio čudan problem sa verzijama: jenv je prikazivao verziju JDK-a 1.8, ali je Maven prikazivao 22.0.1. Ove dve verzije nisu bile usklađene, što je dovelo do neuspeha izgradnje projekta.

Rešenje koje sam na kraju pronašao je da jenv ima Maven dodatak (plugin) koji je potrebno aktivirati.
jenv enable-plugin mavenZatim ponovo izvršite jenv global 1.8.0.412 da postavite verziju JDK-a, i nakon izvršavanja exec $SHELL za osvežavanje promenljivih okruženja, pokrenite mvn -v da proverite verziju Maven-a — videćete da su sada usklađene.

Dva: Pregled Maven konfiguracionih fajlova
Maven se zasniva na POM-u (Project Object Model). Sva konfiguracija projekta se nalazi u fajlu pom.xml, uključujući tip projekta, ime, zavisnosti, prilagođavanje dodataka (plugin) itd.
<?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>com.itwanger</groupId>
<artifactId>MavenDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>MavenDemo</name>
</project>- Prvi red je XML zaglavlje koje navodi verziju i način kodiranja ovog XML dokumenta.
- project je root element koji deklariše neke POM-ove vezane namespace-ove i xsd elemente.
- modelVersion navodi verziju trenutnog POM-a; za Maven 3 vrednost može biti samo 4.0.0.
- groupId definiše kojoj organizaciji pripada projekat, obično obrnutim redosledom domena organizacije — na primer, pošto je moja domena itwanger.com, groupId je com.itwanger.
- artifactId definiše jedinstveni ID projekta unutar organizacije.
- version navodi trenutnu verziju projekta; SNAPSHOT znači „snapshot”, što ukazuje na to da je projekat još uvek u razvoju.
- name deklariše korisnički prijatnije ime projekta.
Ova tri elementa — groupId, artifactId i version — definišu osnovne koordinate projekta. U svetu Maven-a, svaki jar i pom se razlikuje na osnovu ovih koordinata.
<project>
...
<dependencies>
<dependency>
<groupId>stvarni projekat</groupId>
<artifactId>modul</artifactId>
<version>verzija</version>
<type>tip zavisnosti</type>
<scope>opseg zavisnosti</scope>
<optional>da li je zavisnost opcionalna</optional>
<!-- uglavnom se koristi za isključivanje tranzitivnih zavisnosti -->
<exclusions>
<exclusion>
<groupId>…</groupId>
<artifactId>…</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependencies>
...
</project>- dependencies može sadržati jedan ili više dependency elemenata, čime se deklariše jedna ili više zavisnosti projekta.
- groupId, artifactId i version čine osnovne koordinate zavisnosti.
- type navodi tip zavisnosti, podrazumevano jar.
- scope navodi opseg zavisnosti ( detalje pogledajte u odeljku Opseg zavisnosti ispod).
- optional označava da li je zavisnost opcionalna (detalje pogledajte u odeljku Opcionalne zavisnosti ispod).
- exclusions služi za isključivanje tranzitivnih zavisnosti (detalje pogledajte u odeljku Isključivanje zavisnosti ispod).
Opseg zavisnosti (dependency scope) ima sledeće varijante:
- compile, podrazumevani opseg zavisnosti, što znači da zavisnost učestvuje u kompilaciji trenutnog projekta, a kasnije i u fazama testiranja i izvršavanja — reč je o prilično jakoj zavisnosti.
- test, znači da zavisnost učestvuje samo u radu vezanom za testiranje, uključujući kompilaciju i izvršavanje koda za testiranje. Tipičan primer je junit.
- runtime, znači da zavisnost ne mora da učestvuje u kompilaciji projekta, ali joj je potrebno učešće u kasnijim fazama testiranja i izvršavanja.
- provided, znači da prilikom pakovanja ne mora biti uključena, jer će je drugi kontejner obezbediti. Ekvivalentno je sa compile, ali se u fazi pakovanja isključuje.
- system, po stepenu učešća je slično sa provided, ali se ne razrešava kroz Maven repozitorijum, što može dovesti do neprenosive izgradnje — koristiti oprezno.

O tranzitivnim zavisnostima:
Uzmimo kao primer projekat account-email koji ima compile-scope zavisnost spring-code, a spring-code ima compile-scope zavisnost commons-logging. Tada će commons-logging postati compile-scope zavisnost projekta account-email — commons-logging je tranzitivna zavisnost account-email-a:

Zahvaljujući mehanizmu tranzitivnih zavisnosti, prilikom korišćenja Spring Framework-a nije potrebno razmišljati o tome od čega on zavisi, niti brinuti o unosu suvišnih zavisnosti. Maven će razrešiti POM svake direktne zavisnosti i uneti potrebne indirektne zavisnosti u trenutni projekat u obliku tranzitivnih zavisnosti.
O opcionalnim zavisnostima:

Ako projekat A zavisi od B, a B zavisi od X i Y, i ako sva tri imaju opseg compile, onda su X i Y compile-scope tranzitivne zavisnosti projekta A. Međutim, ako želite da X i Y ne budu tranzitivne zavisnosti projekta A (odnosno da ih A ne koristi), možete konfigurisati opcionalne zavisnosti na sledeći način:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.itwanger</groupId>
<artifactId>project-b</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.10</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>8.4-701.jdbc3</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>O isključivanju zavisnosti:
Ponekad zavisnost koju unosite sadrži paket zavisnosti koji ne želite, a želite da unesete onaj koji želite — tada se koristi isključivanje zavisnosti. Na primer, na slici ispod, spring-boot-starter-web podrazumevano dolazi sa logback paketom za logovanje, a ja želim da unesem log4j2, pa prvo isključujem zavisnost logback-a, a zatim unosim željeni paket.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.5.6</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- korišćenje log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>2.5.6</version>
</dependency>Prilikom deklarisanja exclusion-a potrebni su samo groupId i artifactId — element version nije potreban, jer groupId i artifactId već jedinstveno određuju neku zavisnost.
Tri: Maven repozitorijumi
U Maven terminologiji, repozitorijum (repository) je lokacija (place) na kojoj se nalaze biblioteke trećih strana i dodaci (plugin) koje projekat koristi (zajednički se nazivaju komponente/artefakti). Svi Maven projekti mogu deliti ovaj repozitorijum — na osnovu koordinata zavisnosti, Maven pronalazi potrebne zavisnosti u repozitorijumu i koristi ih kada je to potrebno.
Na primer, projekat koristi zavisnost dodatka za paginaciju:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.1.0</version>
</dependency>Odgovarajuća putanja u repozitorijumu je:

Repozitorijumi mogu biti sledećih vrsta:

1) Lokalni repozitorijum
Kada Maven izvršava kompilaciju ili testiranje i potrebna mu je datoteka zavisnosti, uvek se oslanja na datoteke iz lokalnog repozitorijuma, na osnovu koordinata.
Podrazumevano, bilo na Windowsu, macOS-u ili Linuxu, svaki korisnik ima direktorijum repozitorijuma pod imenom .m2/repository/ u svom korisničkom direktorijumu.
Ako želite da prilagodite adresu direktorijuma lokalnog repozitorijuma, možete izmeniti fajl ~/.m2/settings.xml i postaviti vrednost elementa localRepository na željenu adresu repozitorijuma, na primer:
<localRepository>/path/to/local/repo</localRepository>Ako ne možete da pronađete ~/.m2/settings.xml, možete ga kopirati iz Maven instalacionog direktorijuma (ranije pomenuti conf direktorijum).
2) Udaljeni repozitorijum
Podrazumevano je lokalni repozitorijum prazan, pa je Maven potrebno konfigurisati sa upotrebljivim udaljenim repozitorijumom, inače Maven prilikom izgradnje (build) neće moći da preuzme zavisnosti.
Centralni repozitorijum (central repository) je jedan takav upotrebljivi udaljeni repozitorijum koji sadrži većinu najpopularnijih open-source Java biblioteka na svetu, kao i izvorni kod, informacije o autorima, podatke o licencama itd.
Međutim, podrazumevani centralni repozitorijum je prilično spor, pa obično biramo Alibaba Maven udaljeni repozitorijum.
<repositories>
<repository>
<id>ali-maven</id>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
</repository>
</repositories>- repositories može sadržati jedan ili više repository elemenata, čime se deklariše jedan ili više repozitorijuma.
- id je jedinstveni identifikator repozitorijuma. Treba napomenuti da Maven-ov ugrađeni centralni repozitorijum koristi id central, pa ako drugi repozitorijum koristi isti id, overrideovaće konfiguraciju centralnog repozitorijuma.
- url pokazuje na adresu repozitorijuma.
- releases i snapshots kontrolišu Maven-ova prava za preuzimanje release i snapshot komponenti.
- Pod-element enabled kada je true označava da se iz repozitorijuma mogu preuzimati kako release tako i snapshot komponente.
- Pod-element updatePolicy konfiguriše učestalost provere ažuriranja sa udaljenog repozitorijuma.
- Podrazumevana vrednost je daily, što znači da se proverava jednom dnevno;
- opcija never znači da se nikada ne proverava;
- opcija always znači da se proverava pri svakoj izgradnji;
- opcija interval:X znači da se proverava na svakih X minuta (X je bilo koji ceo broj).
- Pod-element checksumPolicy konfiguriše strategiju provere kontrolnog zbira (checksum). Pri preuzimanju komponente, Maven vrši proveru, i ako provera ne uspe:
- kada je vrednost checksumPolicy podrazumevana warn, Maven ispisuje upozorenje prilikom izgradnje;
- kada je vrednost fail, Maven prekida izgradnju pri grešci u proveri;
- kada je vrednost ignore, Maven potpuno ignoriše proveru.
Još jedan razlog za postavljanje udaljenog repozitorijuma je olakšavanje deploy-a sopstvenih komponenti projekta na udaljeni repozitorijum radi korišćenja od strane drugih članova tima — tada je potrebno konfigurisati element distributionManagement:
<distributionManagement>
<repository>
<id>releases</id>
<name>public</name>
<url>http://59.50.95.66:8081/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>Snapshots</name>
<url>http://59.50.95.66:8081/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>- repository označava repozitorijum za release (objavljene) verzije komponenti.
- snapshotRepository označava repozitorijum za snapshot verzije (za razvoj i testiranje).
- Oba elementa zahtevaju konfiguraciju id, name i url — id je jedinstveni identifikator udaljenog repozitorijuma, name služi radi lakšeg čitanja, a url označava adresu repozitorijuma.
Nakon konfiguracije, pokrenite komandu mvn clean deploy i Maven će deploy-ovati projekat u odgovarajući udaljeni repozitorijum. Da li je projekat snapshot ili release verzija se razlikuje na osnovu prethodno pomenutih releases i snapshots u konfiguraciji udaljenog repozitorijuma.
3) Ogledalo repozitorijuma (mirror)
Ako repozitorijum X može da pruži sav sadržaj koji je uskladišten u repozitorijumu Y, onda se X može smatrati ogledalom (mirror) repozitorijuma Y. Obično u fajlu settings.xml dodajemo Alibaba Cloud ogledalo:
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>Preko https://developer.aliyun.com/mvn/search možete pregledati adresu Alibaba Cloud ogledala za Maven.
Opcije elementa mirrorOf su:
<mirrorOf>*</mirrorOf>, match-uje sve udaljene repozitorijume.<mirrorOf>external:*</mirrorOf>, match-uje sve udaljene repozitorijume, osim onih na localhost-u i onih koji koristefile://protokol. Drugim rečima, match-uje sve udaljene repozitorijume koji nisu na lokalnoj mašini.<mirrorOf>repo1,repo2</mirrorOf>, match-uje repozitorijume repo1 i repo2, pri čemu se više udaljenih repozitorijuma razdvaja zarezom.<mirrorOf>*,!repo1<mirrorOf>, match-uje sve udaljene repozitorijume, osim repo1 — znak uzvika služi za isključivanje repozitorijuma iz matchovanja.
U gorenjem primeru, <mirrorOf>central</mirrorOf> znači da će svaki zahtev upućen centralnom repozitorijumu biti preusmeren na ovo ogledalo.
4) Privatni server (private repository)
Privatni server je posebna vrsta udaljenog repozitorijuma koji je postavljen unutar lokalne mreže (LAN). On služi kao proksi za udaljene repozitorijume na širokoj mreži (WAN), radi korišćenja od strane Maven korisnika unutar LAN-a. Kada Maven treba da preuzme komponentu, prvo je traži od privatnog servera; ako komponenta ne postoji na privatnom serveru, preuzima se sa spoljnog udaljenog repozitorijuma i kešira na privatni server.
Privatni server ima sledeće prednosti:
- Uštedu na brzini pristupa spoljnoj mreži
- Ubrzava Maven izgradnju
- Povećava stabilnost i poboljšava kontrolu
- Smanjuje opterećenje centralnog repozitorijuma
5) Pretraga repozitorijuma
Preporučujem 2 sajta koji pružaju uslugu pretrage repozitorijuma:
- Sonatype Nexus: https://repository.sonatype.org/
- MVNrepository: http://mvnrepository.com/
Četiri: Korišćenje Maven-a
1) Najčešće Maven komande
mvn clean: pokreće operaciju čišćenja (podrazumevano čisti podatke u target direktorijumu).mvn clean compile: prvo pokreće čišćenje, a zatim kompilaciju; prevodi kod u target direktorijum.mvn clean test: pokreće čišćenje i testiranje.mvn clean package: pokreće čišćenje i pakovanje.mvn clean install: pokreće čišćenje i instalaciju; instalira zapakovan paket u lokalni repozitorijum, kako bi drugi projekti mogli da ga koriste.mvn clean deploy: pokreće čišćenje i objavljivanje (deploy na privatni server).mvn help:effective-settings: prikazuje efektivne informacije o Maven konfiguraciji.
2) Najčešće korišćeni POM atributi
${project.build.sourceDirectory}: glavni direktorijum izvornog koda projekta, podrazumevanosrc/main/java/${project.build.testSourceDirectory}: direktorijum izvornog koda za testove, podrazumevano/src/test/java/${project.build.directory}: izlazni direktorijum izgradnje projekta, podrazumevanotarget/${project.build.outputDirectory}: izlazni direktorijum kompilacije glavnog koda projekta, podrazumevanotarget/classes/${project.build.testOutputDirectory}: izlazni direktorijum kompilacije koda za testiranje, podrazumevanotarget/testclasses/${project.groupId}: groupId projekta.${project.artifactId}: artifactId projekta.${project.version}: verzija projekta, ekvivalentno sa${version}.${project.build.finalName}: naziv izlaznog fajla nakon pakovanja projekta, podrazumevano${project.artifactId}${project.version}.
3) Konfiguracija Maven-a u IntelliJ IDEA

4) Najčešće korišćeni Maven dodaci (plugin)
Dodaci (plugin) su osnovna funkcionalnost Maven-a koja omogućava ponovno korišćenje zajedničke logike izgradnje kroz više projekata. Dodaci se mogu koristiti za:
- kreiranje jar fajlova,
- kreiranje war fajlova,
- kompilaciju koda,
- izvršavanje jediničnih testova,
- kreiranje dokumentacije projekta itd.
Najčešće korišćeni dodaci su:
- maven-antrun-plugin — omogućava korisnicima da pokreću Ant zadatke u Maven projektu. Korisnici mogu direktno u konfiguraciji ovog dodatka pisati Target na Ant način, a zatim ga proslediti run cilju ovog dodatka na izvršavanje. U projektima koji se migriraju sa Ant-a na Maven, ovaj dodatak je posebno koristan. Pored toga, kada smatrate da treba napisati zadatke visokog stepena prilagođenosti, a Maven vam deluje nedovoljno fleksibilno, možete ih implementirati na Ant način. run cilj maven-antrun-plugin-a se obično vezuje za životni ciklus i izvršava se zajedno sa njim.
- maven-assembly-plugin — kreira distribuzioni paket projekta, koji može sadržati izvršne fajlove projekta, izvorni kod, readme, skripte za platforme itd. maven-assembly-plugin podržava različite glavne formate kao što su zip, tar.gz, jar i war. Koje fajlove treba zapakovati je visoko kontrolisano — na primer, korisnik može kontrolisati pakovanje na nivou fajla, skupa fajlova, modula ili zavisnosti. Pored toga, podržane su i konfiguracije uključivanja i isključivanja. maven-assembly-plugin zahteva od korisnika da koriste metapodatkovni fajl pod imenom assembly.xml za opisivanje pakovanja; njegov single cilj se može direktno pozvati iz komandne linije ili se može vezati za životni ciklus.
- maven-help-plugin — mali pomoćni alat. Najjednostavniji help:system ispisuje sve dostupne promenljive okruženja i Java sistemske osobine. help:effective-pom i help:effective-settings su najkorisniji — oni ispisuju efektivni POM, odnosno efektivne postavke projekta. Efektivni POM je XML nastao spajanjem svih roditeljskih POM-ova (uključujući Super POM); kada niste sigurni odakle dolaze određene informacije u POM-u, možete pregledati efektivni POM.
- maven-javadoc-plugin — dodatak za javadoc, koji objavljuje javadoc izvornog koda.
Pet: Maven Daemon — brži Maven!
Dok sam pretraživao GitHub, naišao sam na novi projekat: maven-mvnd, koji je danima držao vrh GitHub trending liste.

maven-mvnd se može čitati kao Maven Daemon (Maven proces-demon), sa ciljem da pruži brže vreme izgradnje od Maven-a, nadahnut Gradle-om i Takari-jem (optimizator Maven životnog ciklusa).
Maven i Gradle se mogu reći da su dva giganta među alatkama za izgradnju projekata. Moje lično mišljenje je: Maven nije bolji od Gradle-a, a Gradle nije bolji od Maven-a.

Koliko je samo taj moj stav glatko formulisam.
Prednost Maven-a je stabilnost i pouzdanost — dobro radi na većini projekata, a ekosistem zajednice je veoma razvijen; gotovo svi Java programeri ga koriste. Mana Maven-a je u tome što je za nešto veće projekte izgradnja prespora.
Prednost Gradle-a je dovoljna fleksibilnost i nešto brža izgradnja, jer koristi pozadinske procese i mehanizam keširanja. Mana Gradle-a je u tome što itertacije verzija idu prebrzo, zajednica ne stiže, a za početnike je kriva učenja prilično strma.
mvnd nije prepravljeni Maven, već presekcija delimičnih prednosti Maven ∩ (Gradle & Takari).
mvnd koristi sledeći arhitektonski pristup:
- Interno je ugrađen Maven, tako da nije potrebno zasebno instalirati Maven.
- Koristi proces-demon za izgradnju; demon može opsluživati uzastopne zahteve više mvnd klijenata.
- Koristi ugrađenu GraalVM virtuelnu mašinu, koja u poređenju sa tradicionalnom Java virtuelnom mašinom ima brže vreme pokretanja, manju potrošnju memorije, a njen interni JIT kompajler provodi manje vremena na kompilaciju.
- Ako su svi postojeći demoni zauzeti, može se pokrenuti više novih demona da podrže nove zahteve za izgradnju.
Ovakav arhitektonski pristup dodatno pojačava prednost mvnd-a u performansama.
Hajde da to kratko isprobamo.
mvnd, kao i Maven, radi višeplatformski — podržava Windows, macOS i Linux. Komande za automatsku instalaciju su takođe veoma jednostavne, kao što je prikazano ispod:
# Windows
choco install mvndaemon
# Linux
sdk install mvnd
# macOS
brew install mvndaemon/homebrew-mvnd/mvndRadi lakše demonstracije, ovde ću koristiti ručnu instalaciju, koja je i nešto brža.
Preuzmite release verziju mvnd-a sa sledeće adrese:

Nakon preuzimanja, raspakujte fajl i dodajte bin direktorijum u PATH.
U terminalu izvršite mvnd -v i videćete konfiguracione informacije mvnd-a.

Ako se pojavi greška slična ovoj — da JAVA_HOME nije pronađen — možete, prema uputstvu, dodati svojstvo java.home u odgovarajući fajl, odnosno navesti instalacionu putanju JDK-a.

Pošto sam pre toga napravio jedan Spring Boot projekat, možemo uporediti brzinu izgradnje između Maven-a i mvnd-a.
Prvo izvršite komandu mvn clean package — ukupno vreme je 5.318 sekundi.

Zatim izvršite komandu mvnd clean package — ukupno vreme je 3.225 sekundi.

Nakon nekoliko ponovljenih testiranja, zaključio sam da je mvnd zaista znatno brži od Maven-a! Maven se zadržava na oko 5 sekundi, dok mvnd drži oko 3 sekunde.
Naravno, ovaj moj lokalni Spring Boot projekat je inače veoma jednostavan; za projekte sa dužim vremenom izgradnje, prednost mvnd-a bi bila još izraženija.
Pogledajte kako izgleda mvnd na računaru sa 24 jezgra — pravi je alat za efikasnost!

Reference:
- Dudu MD: http://tengj.top/2018/01/01/maven/
- Hang Jian: „Put izučavanja Java inženjera"
- Xu Xiaobin: https://www.infoq.cn/article/2011/04/xxb-maven-7-plugin
Nadam se da ćete nakon čitanja ovog članka imati preliminarno razumevanje i osnovno savlađivanje Maven-a, i da ćete ove veštine vežbati u stvarnim projektima, kako biste ispunili zahteve inženjeringa projekata.
