Înainte de a intra în ANT, Maven sau Gradle, trebuie să înțelegem mai întâi câteva lucruri legate de ele.
Dependență: În general, o dependență se referă la momentul în care ceva necesită un alt lucru pentru a fi executat. Pur și simplu, „A” are o dependență de „B” dacă „A” are nevoie de „B” pentru a se executa cu succes. În lumea software, o dependență este orice lucru de care aplicația dumneavoastră are nevoie pentru a fi executată cu succes. Practic, este orice bibliotecă de suport extern de care are nevoie aplicația. de exemplu, zuul, hystrix, lombok, jdbc etc.
Ințial, obișnuiam să gestionăm dependențele prin:
- descărcarea manuală de pe internet a fișierului jar al bibliotecii necesare și adăugarea acestuia la proiectul nostru.
- scrierea unui script care va descărca automat biblioteca dintr-o sursă externă prin rețea.
Probleme cu care ne confruntăm înainte de aceste instrumente:
- Adăugarea dependențelor prin descărcarea manuală de pe internet este o sarcină foarte obositoare.
- Scripturile noastre ar putea eșua dacă URL-ul sursei externe se schimbă pe internet.
- Este foarte dificil să identificăm și să gestionăm dependențele tranzitive în aplicația noastră.
Strument de gestionare a dependențelor: Rezolvă și gestionează dependențele cerute de aplicație.
Strument de construire: Automatizează crearea de aplicații executabile din codul sursă. Construirea încorporează compilarea, legarea și împachetarea codului într-o formă utilizabilă sau executabilă. Automatizarea construcției implică:
- Descărcarea dependențelor
- Compilarea codului sursă în cod binar
- Împachetarea acelui cod binar
- Executarea testelor
- Desfășurarea în sistemele de producție
Managementul dependențelor și instrumentele de construcție în java:
- ANT + Ivy (2000/2004)
- Maven (2004)
- Gradle (2012)
Apache ANT (Another Neat Tool) este un proiect open source realizat de Apache, lansat în anul 2000. Este o bibliotecă java utilizată pentru automatizarea proceselor de construire a aplicațiilor java. De asemenea, poate fi utilizată și pentru construirea de aplicații non-java. Urmează principiul „Configuration over convention”. În Ant, diferitele faze ale procesului de construire se numesc „Targets”. Fișierele de construcție ANT sunt scrise în XML și, prin convenție, se numesc „build.xml”. Acesta conține trei elemente: proiect, țintă și sarcină. Fiecare fișier de construire conține un proiect. Fiecare lucru din build.xml se află sub elementul project. Proiectul conține cel puțin o țintă (implicit). Target conține un set de sarcini în interiorul său și definește o anumită stare a procesului de construire. O sarcină este o bucată de cod care poate fi executată. Fiecărui nod îi pot fi asociate atribute:
Atribute ale proiectului:
- Name: Numele proiectului.
- Basedir: Dosarul rădăcină pentru proiect și este opțional.
- Default: Ținta implicită pentru construcție. Proiectul poate avea unul sau mai multe numere de ținte. Se utilizează pentru a specifica ținta implicită a proiectului.
Atribute ale țintei:
- Name: Numele țintei.
- Descriere: O descriere despre țintă.
- Depinde: Lista tuturor țintelor, separate prin virgulă, de care depinde această țintă.
- If: Ținta este executată dacă atributul este true.
- Unless: Ținta este executată dacă atributul nu este setat.
Exemplu Build.xml:
<?xml version="1.0"?>
<project>
<target name="hello">
<echo>Hello, World</echo>
</target>
</project>
Adaugă dependență în Ant + Ivy:
<dependency org="org.projectlombok" name="lombok" rev="1.18.10"/>
Principalul beneficiu al Ant este flexibilitatea sa. Ant nu impune dezvoltatorului nicio convenție de codare sau structură de proiect. În consecință, acest lucru înseamnă că Ant cere dezvoltatorilor să scrie singuri toate comenzile, ceea ce duce uneori la fișiere de compilare mari și sunt greu de întreținut. Inițial, Ant nu avea un suport încorporat pentru gestionarea dependențelor. Ulterior, a adoptat Apache Ivy, dezvoltat ca subproiect al proiectului Apache Ant, în scopul gestionării dependențelor.
Apache Maven
Este un instrument de gestionare a dependențelor și de automatizare a construcției, lansat în 2004. Utilizează în continuare XML, dar depășește dezavantajele prin respectarea principiului „Convention over configuration”. Se bazează pe convenții și oferă comenzi predefinite (obiective). Fișierul său de configurare, care conține instrucțiuni de construire și de gestionare a dependențelor, se numește prin convenție „pom.xml” și este prezent în folderul rădăcină al proiectului.
Motorul Maven ia pom.xml și proiectul ca intrări. Acesta citește fișierul pom.xml și descarcă dependențele menționate în acesta sub formă de fișiere jar în depozitul local. Apoi, execută ciclurile de viață, fazele de construcție și pluginurile. În final, este generat un artefact împachetat și testat.
exemplu pom.xml:
Câteva etichete importante din fișierul pom.xml:
- groupId: Reprezintă organizația din care face parte proiectul.
- artifactId: Este numele proiectului.
- version: Reprezintă versiunea proiectului.
- packaging: Reprezintă forma finală de construire a proiectului. de exemplu, jar, war.
Adaugă dependență în maven:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
Repozitoriu maven:
Un depozit este un director în care există toate fișierele jar împachetate împreună cu propriile fișiere pom. Aceste fișiere pom conțin dependențele externe ale proiectului respectiv. În acest fel, maven descarcă dependența de dependențele proiectului dvs. în mod recursiv până când toate dependențele necesare sunt prezente în depozitul dvs. local. Există trei tipuri de depozite în maven:
- Depozit local: Este un depozit prezent chiar pe mașina dezvoltatorului.
- Depozit la nivel de organizație/depozit la distanță: Este un depozit prezent în cadrul organizației.
- Depozit central: Este un depozit aflat pe internet, creat și întreținut de comunitatea maven.
De fiecare dată când o dependență este specificată în fișierul pom.xml al unui proiect, maven o caută în depozitul local. Dacă nu este găsită acolo, o caută în depozitul îndepărtat/org wide repository. Dacă nu este prezentă nici acolo, atunci o caută în depozitul central.
Maven prescrie o structură strictă a proiectului, în timp ce Ant oferă flexibilitate și acolo. Convențiile stricte ale acestuia vin cu prețul de a fi mult mai puțin flexibil decât Ant – personalizarea obiectivelor este foarte greu de realizat.
Dezavantajele lui maven:
- Managementul dependențelor nu gestionează bine conflictele între diferite versiuni ale aceleiași biblioteci.
- Personalizarea obiectivelor este dificilă.
Gradle
Este un instrument open-source de gestionare a dependențelor și de automatizare a construcției, lansat în 2012. Acesta combină părțile bune ale Apache Ant și Apache Maven și se construiește pe baza acestora și utilizează un limbaj specific domeniului (bazat pe Groovy) în loc de XML. A adoptat flexibilitatea de la Ant și ciclul său de viață de la Maven. De asemenea, urmează principiul „Convenția în locul configurației”. Sprijină depozitele Maven și Ivy pentru a prelua dependențele. Fișierul său de configurare este, prin convenție, cunoscut sub numele de „build.gradle” și este prezent în folderul rădăcină al proiectului. Gradle a dat etapelor sale de construire numele de „tasks”, spre deosebire de „targets” de la Ant sau „phases” de la Maven. Google a adoptat Gradle ca instrument de construcție implicit pentru sistemul de operare Android.
Gradle nu folosește XML. În schimb, a avut propriul său limbaj specific domeniului bazat pe Groovy (unul dintre limbajele JVM). Ca urmare, scripturile de compilare Gradle tind să fie mult mai scurte și mai clare decât cele scrise pentru Ant sau Maven. Cantitatea de cod boilerplate este mult mai mică cu Gradle.
Configurări Gradle
- implementare: Se folosește pentru a declara dependențele pe care nu dorim să le expunem la compilarea consumatorilor noștri.
- api: Se utilizează pentru a declara dependențele care fac parte din API-ul nostru, adică pentru dependențele pe care dorim în mod explicit să le expunem consumatorilor noștri.
- compileOnly: Ne permite să declarăm dependențe care ar trebui să fie disponibile doar la compilare, dar care nu sunt necesare în timpul execuției. Un exemplu de utilizare a acestei configurații este un procesor de adnotări precum Lombok, care modifică codul de octet în momentul compilării. După compilare, nu mai este necesar, astfel încât dependența nu este disponibilă în timpul execuției.
- runtimeOnly: Ne permite să declarăm dependențe care nu sunt necesare în momentul compilării, dar care vor fi disponibile în momentul execuției. Un exemplu este SLF4J, unde includem
slf4j-api
în configurațiaimplementation
și o implementare a acelei API (cum ar fislf4j-log4j12
saulogback-classic
) în configurațiaruntimeOnly
. - testImplementation: Similar cu
implementation
, dar dependențele declarate cutestImplementation
sunt disponibile numai în timpul compilării și al execuției testelor. O putem folosi pentru a declara dependențe pentru cadre de testare precum JUnit sau Mockito de care avem nevoie doar în teste și care nu ar trebui să fie disponibile în codul de producție. - testCompileOnly: Similar cu
compileOnly
, dar dependențele declarate cutestCompileOnly
sunt disponibile doar în timpul compilării testelor și nu în timpul execuției. - testRuntimeOnly: Similar cu
runtimeOnly
, dar dependențele declarate cutestRuntimeOnly
sunt disponibile numai în timpul execuției testelor și nu în timpul compilării.
Proiecte și sarcini în Gradle
Care construcție Gradle constă din unul sau mai multe proiecte. Fiecare proiect constă dintr-un set de sarcini. Fiecare sarcină reprezintă o singură lucrare pe care o execută un build, de exemplu, generarea JavaDoc, publicarea unor arhive într-un depozit etc.
exemplu de build.gradle
Depozitul Gradle:
„Aliasurile” din Gradle sunt utilizate în cazul adăugării depozitelor Maven la build-ul proiectului nostru. Aceste alias-uri sunt următoarele:
- mavenCentral(): Acest alias reprezintă dependențele care sunt preluate din depozitul central Maven 2.
- jcenter(): Acest alias reprezintă dependențele care sunt preluate din depozitul Maven JCenter al Bintray.
- mavenLocal(): Acest alias reprezintă dependențele care sunt preluate din depozitul Maven local.
Exemplu: Adăugați depozitul Maven central în proiectul nostru, adăugați următorul fragment de cod la fișierul nostru ‘build.gradle’:
repositories {
mavenCentral()
}
Adaugați o dependență în Gradle:
compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
Avantaje:
- Se descurcă destul de bine cu dependențele tranzitive. Dacă există o dependență tranzitivă conflictuală în proiect, atunci, pentru a o rezolva, selectează cea mai recentă versiune a dependenței. De exemplu, dependența „A” necesită în mod intern dependența „C” cu versiunea 2.0 și dependența „B” necesită în mod intern dependența „C” cu versiunea 3.0. Atunci Gradle va utiliza cea mai recentă versiune a dependenței ‘C’.
- Filele de configurare Gradle au dimensiuni mai mici și sunt mai curate, deoarece utilizează un limbaj specific domeniului, bazat pe Groovy în loc de XML.
- Gradle utilizează conceptul de construire incrementală și evită munca prin urmărirea intrărilor și ieșirilor sarcinilor și prin rularea doar a ceea ce este necesar, precum și prin procesarea doar a fișierelor care s-au modificat atunci când este posibil și, prin urmare, funcționează mai rapid decât maven.
.