ANT vs Maven vs Gradle

För att kunna sätta oss in i ANT, Maven eller Gradle måste vi först förstå några saker som har med dem att göra.

Beroende: I allmänhet avses ett beroende när något kräver en annan sak för att kunna utföras. Enkelt uttryckt är ”A” beroende av ”B” om ”A” kräver ”B” för att kunna utföras. I programvaruvärlden är ett beroende något som ditt program kräver för att kunna utföras framgångsrikt. Det är i princip alla externa stödbibliotek som krävs av programmet, t.ex. zuul, hystrix, lombok, jdbc etc.

I början hanterade vi beroenden genom att:

  • hämta jar-filen för det nödvändiga biblioteket manuellt från internet och lägga till den i vårt projekt.
  • skriva ett skript som automatiskt hämtar biblioteket från en extern källa via nätverket.

Problem som vi möter innan dessa verktyg:

  • Att lägga till beroenden genom att manuellt hämta dem från internet är en mycket tröttsam uppgift.
  • Våra skript kan misslyckas om URL:en för den externa källan ändras över internet.
  • Det är mycket svårt att identifiera och hantera de transitiva beroendena i vår applikation.

Verktyg för hantering av beroenden: Det löser och hanterar de beroenden som krävs av applikationen.

Byggverktyg: Det automatiserar skapandet av körbara program från källkoden. Byggandet omfattar kompilering, länkning och paketering av koden till en användbar eller körbar form. Automatisering av byggandet omfattar:

  1. Hämtning av beroenden
  2. Kompilering av källkod till binär kod
  3. Packning av den binära koden
  4. Körning av tester
  5. Uppsättning till produktionssystem

Beroendehantering och byggverktyg i java:

  • ANT + Ivy (2000/2004)
  • Maven (2004)
  • Gradle (2012)

Apache ANT (Another Neat Tool) är ett projekt med öppen källkod från Apache som släpptes år 2000. Det är ett javabibliotek som används för att automatisera byggprocesserna för javaprogram. Det kan också användas för att bygga icke-javaapplikationer. Det följer principen ”Configuration over convention”. I Ant kallas olika faser av byggprocessen för ”Targets”. ANT:s byggfiler är skrivna i XML och kallas enligt konvention ”build.xml”. Den innehåller tre element: projekt, mål och uppgift. Varje byggfil innehåller ett projekt. Varenda sak i build.xml finns under elementet project. Projekt innehåller minst ett mål (standard). Target innehåller en uppsättning uppgifter inom sig och definierar ett specifikt tillstånd i byggprocessen. En uppgift är en bit kod som kan exekveras. Varje nod kan ha attribut kopplade till sig:

Attribut för projekt:

  • Namn:
  • Basedir: Projektets namn: Det är valfritt.
  • Standard: Projektets rotmapp: Det är valfritt.
  • Standard: Projektets rotmapp: Standardmålet för byggandet. Projektet kan ha ett eller flera mål. Det används för att ange projektets standardmål.

Attribut för mål:

  • Namn:
  • Beskrivning: Målets namn: Beskrivning av målet.
  • Beror på: Lista över alla mål, separerade med kommatecken, som detta mål är beroende av.
  • Om: Målet utförs om attributet är sant.
  • Om inte: Målet utförs om attributet är sant: Målet exekveras om attributet inte är inställt.

Build.xml exempel:

<?xml version="1.0"?>
<project>
<target name="hello">
<echo>Hello, World</echo>
</target>
</project>

Add dependency in Ant + Ivy:

<dependency org="org.projectlombok" name="lombok" rev="1.18.10"/>

Den största fördelen med Ant är dess flexibilitet. Ant ålägger inte utvecklaren några kodningskonventioner eller projektstruktur. Följaktligen innebär detta att Ant kräver att utvecklarna skriver alla kommandon själva, vilket ibland leder till stora byggfiler och är svåra att underhålla. Ursprungligen hade Ant inget inbyggt stöd för beroendehantering. Senare antog man Apache Ivy, som utvecklats som ett underprojekt till Apache Ant-projektet, i syfte att hantera beroenden.

Apache Maven

Det är ett verktyg för hantering av beroenden och automatiserad byggning som släpptes 2004. Det fortsätter att använda XML men övervinner nackdelarna genom att följa principen ”Convention over configuration”. Det bygger på konventioner och tillhandahåller fördefinierade kommandon (mål). Dess konfigurationsfil, som innehåller bygg- och beroendehanteringsinstruktioner, kallas enligt konvention ”pom.xml” och finns i projektets rotmapp.

Maven-arbetsflöde

Maven-motorn tar pom.xml och projektet som indata. Den läser pom.xml-filen och hämtar de beroenden som nämns i den som jar-filer till det lokala arkivet. Därefter utför den livscyklerna, byggfaserna och plugins. I slutändan genereras en paketerad och testad artefakt.

pom.xml exempel:

Några viktiga taggar i pom.xml-filen:

  • groupId:
  • artefactId: Den representerar den organisation som projektet tillhör.
  • artefactId: Den representerar den organisation som projektet tillhör: Det är namnet på projektet.
  • version: Den representerar projektets version.
  • packaging: Den representerar projektets version: Den representerar den slutliga formen för byggandet av projektet. t.ex. jar, war.

Add dependency in maven:

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>

Maven repository:

Ett repository är en katalog där alla paketerade jar-filer finns tillsammans med sina egna pom-filer. Dessa pom-filer innehåller projektets externa beroenden. På detta sätt laddar maven ner beroenden av beroenden för ditt projekt rekursivt tills alla nödvändiga beroenden finns i ditt lokala arkiv. Det finns tre typer av arkiv i maven:

  1. Lokalt arkiv:
  2. Organisationsnivå/fjärrförråd: Detta är ett förråd som finns på utvecklarens egen maskin: Det är ett arkiv som finns inom organisationen.
  3. Centralt arkiv:

När ett beroende specificeras i pom.xml-filen för ett projekt söker maven efter det i det lokala arkivet. Om det inte hittas där letar den efter det i det externa/org wide repository. Om det inte finns ens där letar den efter det i det centrala repository.

Maven föreskriver en strikt projektstruktur, medan Ant ger flexibilitet även där. Dess strikta konventioner kommer med priset att den är mycket mindre flexibel än Ant – målanpassning är mycket svår.

Nackdelar med maven:

  1. Dependency management hanterar inte konflikter väl mellan olika versioner av samma bibliotek.
  2. Anpassning av mål är svårt.

Gradle

Det är ett verktyg för beroendehantering och byggautomation med öppen källkod som släpptes 2012. Det kombinerar de goda delarna av Apache Ant och Apache Maven och bygger ovanpå dem och använder ett domänspecifikt språk (baserat på Groovy) istället för XML. Det har antagit flexibilitet från Ant och sin livscykel från Maven. Den följer också principen ”Convention over configuration”. Den stöder Maven- och Ivy-arkiv för att hämta beroenden. Konfigurationsfilen kallas enligt konvention ”build.gradle” och finns i projektets rotmapp. Gradle gav sina byggsteg namnet ”tasks”, till skillnad från Ant’s ”targets” eller Maven’s ”phases”. Google antog Gradle som standardbyggverktyg för Android OS.

Gradle använder inte XML. Istället hade det ett eget domänspecifikt språk baserat på Groovy (ett av JVM-språken). Som ett resultat tenderar Gradle-byggskripten att vara mycket kortare och tydligare än de som är skrivna för Ant eller Maven. Mängden boilerplate-kod är mycket mindre med Gradle.

Gradle konfigurationer

  • implementering: Den används för att deklarera beroenden som vi inte vill exponera för våra konsumenters kompileringstid.
  • api: Det används för att deklarera beroenden som är en del av vårt API, dvs. för beroenden som vi uttryckligen vill exponera för våra konsumenter.
  • compileOnly: Det gör det möjligt för oss att deklarera beroenden som endast ska vara tillgängliga vid kompileringstid, men som inte behövs vid körtid. Ett exempel på användningsfall för den här konfigurationen är en annotationsbehandlare som Lombok, som ändrar bytekoden vid kompileringstid. Efter kompilering behövs den inte längre, så beroendet är inte tillgängligt vid körning.
  • runtimeOnly: Det gör det möjligt att deklarera beroenden som inte behövs vid kompilering, men som kommer att vara tillgängliga vid körning. Ett exempel är SLF4J där vi inkluderar slf4j-api till implementation-konfigurationen och en implementering av det API:et (som slf4j-log4j12 eller logback-classic) till runtimeOnly-konfigurationen.
  • testImplementation: Liknande implementation, men beroenden som deklareras med testImplementation är endast tillgängliga under kompilering och körning av tester. Vi kan använda det för att deklarera beroenden till testramverk som JUnit eller Mockito som vi bara behöver i tester och som inte ska vara tillgängliga i produktionskoden.
  • testCompileOnly: Liknande compileOnly, men beroenden som deklareras med testCompileOnly är endast tillgängliga under kompilering av tester och inte vid körning.
  • testRuntimeOnly: Liknande runtimeOnly, men beroenden som deklareras med testRuntimeOnly är endast tillgängliga under körning av tester och inte vid kompilering.

Projekt och uppgifter i Gradle

Varje Gradle-bygge består av ett eller flera projekt. Varje projekt består av en uppsättning uppgifter. Varje uppgift representerar ett enskilt arbete som en build utför t.ex. generera JavaDoc, publicera några arkiv till ett repository etc.

build.gradle example

Gradle repository:

”Aliaserna” i Gradle används om vi ska lägga till Maven-repositories till vår projektbuild. Dessa alias är följande:

  • mavenCentral():
  • jcenter(): Detta alias står för de beroenden som hämtas från det centrala Maven 2-förrådet:
  • mavenLocal(): Detta alias står för de beroenden som hämtas från Bintrays JCenter Maven-förråd.
  • mavenLocal(): Detta alias står för de beroenden som hämtas från Bintrays JCenter Maven-förråd:

Exempel: Lägg till det centrala Maven-förrådet i vårt projekt, lägg till följande kodutdrag i vår fil ”build.gradle”:

repositories {
mavenCentral()
}

Add dependency in Gradle:

compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'

Fördelar:

  1. Det hanterar transitiva beroenden ganska bra. Om det finns ett konfliktfyllt transitivt beroende i projektet väljer den den senaste versionen av beroendet för att lösa det. Exempelvis kräver beroende ”A” internt beroende ”C” med version 2.0 och beroende ”B” kräver internt beroende ”C” med version 3.0. Då kommer Gradle att använda den senaste versionen av beroendet ”C”.
  2. Gradles konfigurationsfiler är mindre och renare eftersom den använder ett domänspecifikt språk, baserat på Groovy istället för XML.
  3. Gradle använder sig av ett inkrementellt byggkoncept och undviker arbete genom att spåra in- och utdata från uppgifter och endast köra det som är nödvändigt och endast bearbeta filer som har ändrats när det är möjligt, vilket gör att den är snabbare än maven.

Lämna en kommentar