TheNEXUS

1.7. Vergelijking van Maven met Ant

De auteurs van dit boek hebben geen belang bij het creëren van een vete tussen Apache Ant en Apache Maven, maar we zijn ons ook bewust van het feit dat de meeste organisaties een beslissing moeten nemen tussen de twee standaard oplossingen: Apache Ant en Apache Maven. In deze sectie vergelijken en contrasteren we de tools.

Ant blinkt uit in het bouwproces, het is een bouwsysteem gemodelleerd naar make met targets en dependencies. Elk doel bestaat uit een reeks instructies die zijn gecodeerd in XML. Er is een copy-taak en eenjavac-taak, evenals een jar-taak. Als u Ant gebruikt, geeft u Ant specifieke instructies voor het compileren en verpakken van uw uitvoer. Kijk eens naar het volgende voorbeeld van een eenvoudig build.xml bestand:

Een eenvoudig Ant build.xml bestand.

<project name="my-project" default="dist" basedir="."> <description> simple example build file </description> <!-- set global properties for this build --> <property name="src" location="src/main/java"/> <property name="build" location="target/classes"/> <property name="dist" location="target"/> <target name="init"> <!-- Create the time stamp --> <tstamp/> <!-- Create the build directory structure used by compile --> <mkdir dir="${build}"/> </target> <target name="compile" depends="init" description="compile the source " > <!-- Compile the java code from ${src} into ${build} --> <javac srcdir="${src}" destdir="${build}"/> </target> <target name="dist" depends="compile" description="generate the distribution" > <!-- Create the distribution directory --> <mkdir dir="${dist}/lib"/> <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file --> <jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/> </target> <target name="clean" description="clean up" > <!-- Delete the ${build} and ${dist} directory trees --> <delete dir="${build}"/> <delete dir="${dist}"/> </target></project>

In dit eenvoudige Ant voorbeeld kun je zien hoe je Antex precies moet vertellen wat te doen. Er is een compile doel dat de javactaak bevat die de broncode in de src/main/java directory compileert naar detarget/classes directory. Je moet Ant precies vertellen waar je broncode staat, waar je de resulterende bytecode wilt opslaan en hoe je dit alles in een JAR-bestand moet verpakken. Hoewel er een aantal recente ontwikkelingen zijn die helpen om Ant minder procedureel te maken, is de ervaring van een ontwikkelaar met Ant het coderen van een procedurele taal geschreven in XML.

Contrasteer het vorige Ant voorbeeld met een Maven voorbeeld. In Maven, om een JAR bestand te maken van een Java bron, hoef je alleen maar een eenvoudige pom.xml te maken, je broncode in${basedir}/src/main/java te plaatsen en dan mvn install uit te voeren vanaf de commandoregel. Het voorbeeld Maven pom.xml dat de resultaten bereikt van het eenvoudige Ant bestand in A Simple Ant build.xml bestand wordt getoond in A Sample Maven pom.xml.

A Sample Maven pom.xml.

<project> <modelVersion>4.0.0</modelVersion> <groupId>org.sonatype.mavenbook</groupId> <artifactId>my-project</artifactId> <version>1.0</version></project>

Dat is alles wat je nodig hebt in je pom.xml. Het uitvoeren van mvn install vanaf de commandoregel zal resources verwerken, broncode compileren, unittests uitvoeren, een JAR maken, en de JAR in een lokale repository installeren voor hergebruik in andere projecten. Zonder aanpassing kun je mvn site uitvoeren en dan een index.html bestand vinden in target/site dat links bevat naar JavaDoc en een paar rapporten over je broncode.

Toegegeven, dit is het eenvoudigst mogelijke voorbeeld project dat niets meer dan wat broncode bevat en een eenvoudige JAR produceert. Het is een project dat de Maven conventies volgt en geen afhankelijkheden of maatwerk nodig heeft. Als we het gedrag willen gaan aanpassen, zal onze pom.xml groter worden, en in de grootste projecten kan je verzamelingen zien van zeer complexe Maven POMs die een grote hoeveelheid plugin aanpassingen en afhankelijkhedendeclaraties bevatten. Maar, zelfs wanneer de POM bestanden van je project substantiëler worden, bevatten ze een heel ander soort informatie dan het build bestand van een even groot project dat Ant gebruikt. Maven POMs bevatten declaraties: “Dit is een JAR project”, en “De broncode staat in src/main/java”. De bouwbestanden van Ant bevatten expliciete instructies: “Dit is een project”, “De broncode staat in src/main/java”, “Run javacagain this directory”, “Zet de resultaten in target/classes”, “Maak een JAR van de ….”, enz. Waar Ant expliciet moest zijn over het proces, was er iets “ingebouwd” in Maven dat gewoon wist waar de broncode was en hoe die verwerkt moest worden.

De verschillen tussen Ant en Maven in dit voorbeeld zijn:

  • Apache Ant

    • Ant heeft geen formele conventies zoals een gemeenschappelijke projectdirectory structuur of standaard gedrag. Je moet Ant precies vertellen waar hij de broncode kan vinden en waar hij de uitvoer moet plaatsen. Informele conventies zijn in de loop der tijd ontstaan, maar ze zijn niet gecodificeerd in het product.
    • Ant is procedureel. Je moet Ant precies vertellen wat hij moet doen en wanneer hij dat moet doen. Je moet Ant vertellen dat hij moet compileren, dan kopiëren, dan comprimeren.
    • Ant heeft geen levenscyclus. Je moet doelen en doelafhankelijkheden definiëren. Je moet handmatig een reeks taken aan elk doel koppelen.
  • Apache Maven

    • Maven heeft conventies. Het weet waar je broncode is omdat je de conventie hebt gevolgd. Maven’s Compiler plugin zet de bytecode in target/classes, en het produceert een JAR bestand in target.
    • Maven is declaratief. Alles wat je hoefde te doen was een pom.xml bestand te maken en je broncode in de standaard directory te zetten. Maven zorgde voor de rest.
    • Maven heeft een lifecycle die werd aangeroepen toen je mvn install uitvoerde. Dit commando vertelde Maven om een serie opeenvolgende lifecycle fases uit te voeren totdat het de install lifecycle fase bereikte. Als een neveneffect van deze reis door de lifecycle, voerde Maven een aantal standaard plugin doelen uit die dingen deden zoals compileren en een JAR maken.

Maven heeft ingebouwde intelligentie over gemeenschappelijke project taken in de vorm van Maven plugins. Als je unit tests wilt schrijven en uitvoeren, hoef je alleen maar de tests te schrijven, ze in ${basedir}/src/test/java te plaatsen, een test-afhankelijkheid van TestNG of JUnit toe te voegen, en mvn test uit te voeren. Als je een web applicatie wilt deployen en niet een JAR, hoef je alleen maar je project type te veranderen in war en je docroot in${basedir}/src/main/webapp te zetten. Natuurlijk, je kunt dit allemaal doen met Ant, maar dan moet je de instructies vanaf nul schrijven. In Ant moet je eerst uitzoeken waar het JUnit JAR bestand moet komen. Dan moet je een classpath maken dat het JUnitJAR bestand bevat. Dan vertel je Ant waar het moet zoeken naar test broncode, schrijf je een doel dat de test broncode compileert naar bytecode, en voer je de unit tests uit met JUnit.

Zonder ondersteunende technologieën als antlibs en Ivy (zelfs met deze ondersteunende technologieën), heeft Ant het gevoel van een c`ustom proceduralbuild. Een efficiënte set van Maven POMs in een project dat zich houdt aan Maven’s veronderstelde conventies heeft verrassend weinig XML vergeleken met het Ant alternatief. Een ander voordeel van Maven is de afhankelijkheid van wijd gedeelde Maven plugins. Iedereen gebruikt de Maven Surefire plugin voor unit testen, en als iemand ondersteuning voor een nieuw unit testframework toevoegt, kun je nieuwe mogelijkheden in je eigen build krijgen door gewoon de versie van een bepaalde Maven plugin in de POM van je project te verhogen.

De beslissing om Maven of Ant te gebruiken is geen binaire, en Ant heeft nog steeds een plaats in een complexe build. Als je huidige build een zeer aangepast proces bevat, of als je een aantal Ant scripts hebt geschreven om een specifiek proces op een specifieke manier te voltooien dat niet kan worden aangepast aan de Maven standaarden, dan kun je deze scripts nog steeds gebruiken met Maven. Ant is beschikbaar gemaakt als een core Maven plugin. Aangepaste Maven plugins kunnen worden geïmplementeerd in Ant, en Maven projecten kunnen worden geconfigureerd om Ant scripts uit te voeren binnen de Maven project lifecycle.

Leave a Reply