ANT vs Maven vs Gradle

Voordat we ons gaan verdiepen in ANT, Maven of Gradle, moeten we eerst een paar dingen begrijpen die met hen te maken hebben.

Dependency: In het algemeen verwijst een afhankelijkheid naar wanneer iets een ander ding vereist om zelf uitgevoerd te worden. Simpel gezegd, “A” heeft een afhankelijkheid van “B” als “A” vereist “B” voor zijn succesvolle uitvoering. In de softwarewereld is een afhankelijkheid alles wat uw applicatie nodig heeft voor een succesvolle uitvoering. Het is in principe elke externe ondersteunende bibliotheek die nodig is voor de toepassing. bijvoorbeeld zuul, hystrix, lombok, jdbc, etc.

In eerste instantie, we gebruikt om afhankelijkheden te beheren door:

  • het jar-bestand van de vereiste bibliotheek handmatig downloaden van het internet en toe te voegen aan ons project.
  • het schrijven van een script dat automatisch de bibliotheek zal downloaden van een externe bron via het netwerk.

Problemen geconfronteerd voordat deze tools:

  • Het toevoegen van de afhankelijkheden door ze handmatig te downloaden van het internet is een zeer vermoeiende taak.
  • Onze scripts kunnen mislukken als de URL van de externe bron verandert via het internet.
  • Het is erg moeilijk om te identificeren en beheren van de transitieve afhankelijkheden in onze applicatie.

Dependency management tool: Het lost op en beheert de afhankelijkheden die nodig zijn voor de toepassing.

Build tool: Het automatiseert de creatie van uitvoerbare toepassingen uit de broncode. Het bouwen omvat het compileren, koppelen en verpakken van de code in een bruikbare of uitvoerbare vorm. Build automation omvat:

  1. Downloading van afhankelijkheden
  2. Compilatie van broncode in binaire code
  3. Packaging van die binaire code
  4. Running van tests
  5. Deployment naar productiesystemen

Dependency management en build tools in java:

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

Apache ANT (Another Neat Tool) is een open source project van Apache, uitgebracht in het jaar 2000. Het is een java-bibliotheek die wordt gebruikt voor het automatiseren van de bouwprocessen voor java-toepassingen. Het kan ook worden gebruikt voor het bouwen van niet-java applicaties. Het volgt het principe van “Configuratie boven conventie”. In Ant worden de verschillende fasen van het bouwproces “Targets” genoemd. ANT bouwbestanden zijn geschreven in XML en worden volgens afspraak “build.xml” genoemd. Het bevat drie elementen: project, target en task. Elk build bestand bevat één project. Elk ding in de build.xml staat onder het project element. Project bevat ten minste één doel (standaard). Target bevat een set van taken en definieert een specifieke staat van het bouwproces. Een taak is een stuk code dat kan worden uitgevoerd. Aan elk knooppunt kunnen attributen worden gekoppeld:

Attributen van Project:

  • Naam: De naam van het project.
  • Basedir: De hoofdmap voor het project en deze is optioneel.
  • Default: Het standaard doel voor de build. Het project kan een of meer targets hebben. Het wordt gebruikt om het standaard target van het project op te geven.

Attributen van Target:

  • Naam: De naam van de target.
  • Description: Een beschrijving over het target.
  • Depends: Lijst van alle targets, gescheiden door komma waar deze target van afhankelijk is.
  • Als: Het target wordt uitgevoerd als het attribuut waar is.
  • Tenzij: Het target wordt uitgevoerd als het attribuut niet is ingesteld.

Build.xml voorbeeld:

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

Voeg dependency toe in Ant + Ivy:

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

Het belangrijkste voordeel van Ant is zijn flexibiliteit. Ant legt geen coderingsconventies of projectstructuur op aan de ontwikkelaar. Dit betekent dat Ant van ontwikkelaars eist dat ze alle commando’s zelf schrijven, wat soms leidt tot grote build-bestanden en moeilijk te onderhouden zijn. Aanvankelijk had Ant geen ingebouwde ondersteuning voor dependency management. Later adopteerde het Apache Ivy, ontwikkeld als sub-project van het Apache Ant project, voor afhankelijkheidsbeheer.

Apache Maven

Het is een dependency management en een build automation tool, uitgebracht in 2004. Het blijft XML gebruiken, maar overwint de nadelen door het principe van “Conventie boven configuratie” te volgen. Het vertrouwt op conventies en biedt voorgedefinieerde commando’s (doelen). Het configuratiebestand, dat instructies voor het bouwen en afhankelijkhedenbeheer bevat, heet volgens afspraak “pom.xml” en bevindt zich in de hoofdmap van het project.

Maven workflow

Maven engine neemt pom.xml en het project als invoer. Hij leest het pom.xml-bestand en downloadt de daarin vermelde afhankelijkheden als jar-bestanden naar de lokale repository. Dan voert het de levenscycli, bouwfasen en plugins uit. Uiteindelijk wordt een verpakt en getest artefact gegenereerd.

pom.xml voorbeeld:

Enkele belangrijke tags in het pom.xml bestand:

  • groupId: Staat voor de organisatie waartoe het project behoort.
  • artifactId: Het is de naam van het project.
  • version: Het vertegenwoordigt de versie van het project.
  • packaging: Het vertegenwoordigt de uiteindelijke vorm van de build van het project. bijv. jar, war.

Voeg afhankelijkheid toe in maven:

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

Maven repository:

Een repository is een directory waar alle verpakte jar-bestanden bestaan, samen met hun eigen pom-bestanden. Deze pom bestanden bevatten de externe afhankelijkheden van dat project. Op deze manier download maven recursief dependencies van je project totdat alle benodigde dependencies aanwezig zijn in je lokale repository. Er zijn drie soorten repositories in maven:

  1. Lokale repository: Het is een repository aanwezig op de machine van de ontwikkelaar zelf.
  2. Organisatie niveau/remote repository: Het is een repository aanwezig binnen de organisatie.
  3. Centrale repository: Het is een repository over het internet, gemaakt en onderhouden door de maven-gemeenschap.

Wanneer een dependency wordt gespecificeerd in het pom.xml-bestand van een project, zoekt maven ernaar in de lokale repository. Als het daar niet wordt gevonden, wordt het gezocht in de externe/org-brede repository. Als het zelfs daar niet aanwezig is, dan zoekt het in de centrale repository.

Maven schrijft een strikte project structuur voor, terwijl Ant ook daar flexibiliteit biedt. De strikte conventies komen met de prijs dat het veel minder flexibel is dan Ant – doelaanpassing is erg moeilijk.

Tegenvallers van maven:

  1. Dependency management gaat niet goed om met conflicten tussen verschillende versies van dezelfde bibliotheek.
  2. Aanpassing van doelen is moeilijk.

Gradle

Het is een open-source dependency management en build automation tool, uitgebracht in 2012. Het combineert de goede delen van Apache Ant en Apache Maven en bouwt er bovenop en gebruikt een domeinspecifieke taal (gebaseerd op Groovy) in plaats van XML. Het heeft flexibiliteit overgenomen van Ant en zijn levenscyclus van Maven. Het volgt ook het principe van “Conventie boven configuratie”. Het ondersteunt Maven en Ivy repositories om de afhankelijkheden op te halen. Het configuratiebestand is bij conventie bekend als “build.gradle” en bevindt zich in de hoofdmap van het project. Gradle gaf zijn bouwstappen de naam “tasks”, in tegenstelling tot Ant’s “targets” of Maven’s “phases”. Google heeft Gradle geadopteerd als de standaard build tool voor Android OS.

Gradle maakt geen gebruik van XML. In plaats daarvan heeft het zijn eigen Domain Specific Language gebaseerd op Groovy (een van JVM talen). Als gevolg daarvan, Gradle bouwen scripts hebben de neiging om veel korter en duidelijker dan die geschreven voor Ant of Maven. De hoeveelheid boilerplate code is veel kleiner met Gradle.

Gradle configuraties

  • implementatie: Het wordt gebruikt om afhankelijkheden te verklaren die we niet willen blootstellen aan onze consumenten compile time.
  • api: Het wordt gebruikt om afhankelijkheden te declareren die deel uitmaken van onze API, d.w.z. voor afhankelijkheden die we expliciet willen blootstellen aan onze consumenten.
  • compileOnly: Hiermee kunnen we afhankelijkheden declareren die alleen beschikbaar moeten zijn tijdens het compileren, maar niet nodig zijn tijdens runtime. Een voorbeeld van deze configuratie is een annotatieprocessor zoals Lombok, die de bytecode wijzigt tijdens het compileren. Na compilatie is het niet meer nodig, dus is de dependency niet beschikbaar tijdens runtime.
  • runtimeOnly: Hiermee kunnen we afhankelijkheden declareren die niet nodig zijn tijdens het compileren, maar wel beschikbaar zullen zijn tijdens runtime. Een voorbeeld is SLF4J waar we slf4j-api toevoegen aan de implementation configuratie en een implementatie van die API (zoals slf4j-log4j12 of logback-classic) aan de runtimeOnly configuratie.
  • testImplementatie: Vergelijkbaar met implementation, maar afhankelijkheden verklaard met testImplementation zijn alleen beschikbaar tijdens compilatie en runtime van tests. Wij kunnen het gebruiken voor het verklaren van afhankelijkheden aan het testen kaders zoals JUnit of Mockito die wij slechts in tests nodig hebben en die niet beschikbaar in de productiecode zouden moeten zijn.
  • testCompileOnly: Vergelijkbaar met compileOnly, maar afhankelijkheden verklaard met testCompileOnly zijn alleen beschikbaar tijdens het compileren van tests en niet tijdens runtime.
  • testRuntimeOnly: Vergelijkbaar met runtimeOnly, maar afhankelijkheden gedeclareerd met testRuntimeOnly zijn alleen beschikbaar tijdens runtime van tests en niet tijdens compilatietijd.

Projecten en taken in Gradle

Elke Gradle build bestaat uit een of meer projecten. Elk project bestaat uit een set van taken. Elke taak vertegenwoordigt een enkel stuk werk dat een build uitvoert, b.v. JavaDoc genereren, een aantal archieven publiceren naar een repository, etc.

build.gradle voorbeeld

Gradle repository:

De “aliases” in Gradle worden gebruikt in het geval van het toevoegen van Maven repositories aan onze project build. Deze aliassen zijn als volgt:

  • mavenCentral(): Deze alias staat voor de dependencies die worden opgehaald uit de centrale Maven 2 repository.
  • jcenter(): Deze alias staat voor de afhankelijkheden die worden opgehaald uit de JCenter Maven repository van Bintray.
  • mavenLocal(): Dit alias staat voor de afhankelijkheden die worden opgehaald uit de lokale Maven repository.

Voorbeeld: voeg de centrale Maven repository toe in ons project, voeg de volgende code snippet toe aan ons ‘build.gradle’ bestand:

repositories {
mavenCentral()
}

Voeg afhankelijkheid toe in Gradle:

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

Voordelen:

  1. Het behandelt transitieve afhankelijkheden vrij goed. Als er een conflicterende transitieve afhankelijkheid bestaat in het project, dan selecteert het de laatste versie van de afhankelijkheid om het op te lossen. Bijvoorbeeld, afhankelijkheid ‘A’ vereist intern afhankelijkheid ‘C’ met versie 2.0 en afhankelijkheid ‘B’ vereist intern afhankelijkheid ‘C’ met versie 3.0. Dan zal Gradle gebruik maken van de nieuwste versie van de afhankelijkheid ‘C’.
  2. Gradle’s configuratie bestanden zijn kleiner in omvang en schoner als het gebruikt domein specifieke taal, gebaseerd op Groovy in plaats van XML.
  3. Gradle maakt gebruik van incrementele bouwen concept en vermijdt het werk door het bijhouden van input en output van taken en alleen het uitvoeren van wat nodig is, en alleen het verwerken van bestanden die zijn gewijzigd wanneer mogelijk en dus, presteert sneller dan maven.

Plaats een reactie