TheNEXUS

1.7. Confrontando Maven con Ant

Gli autori di questo libro non hanno interesse a creare una faida tra Apache Ant e Apache Maven, ma siamo anche consapevoli del fatto che la maggior parte delle organizzazioni deve prendere una decisione tra le due soluzioni standard: Apache Ant e Apache Maven. In questa sezione, confronteremo e contrasteremo gli strumenti.

Ant eccelle nel processo di compilazione, è un sistema di compilazione modellato dopo makewith target e dipendenze. Ogni target consiste in un insieme di istruzioni che sono codificate in XML. C’è un compito copy e un compito javac così come un compito jar. Quando usate Ant, gli fornite istruzioni specifiche per compilare e impacchettare il vostro prodotto. Guarda il seguente esempio di un semplice file build.xml:

Un semplice file build.xml di Ant.

<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 questo semplice esempio Ant, puoi vedere come devi dire ad Antexactly cosa fare. C’è un obiettivo di compilazione che include il javactask che compila il sorgente nella directory src/main/java nella directorytarget/classes. Dovete dire ad Ant esattamente dove si trova il vostro sorgente, dove volete che il bytecode risultante sia memorizzato, e come impacchettare il tutto in un file JAR. Mentre ci sono alcuni recenti sviluppi che aiutano a rendere Ant meno procedurale, l’esperienza di uno sviluppatore con Ant è nella codifica di un linguaggio procedurale scritto in XML.

Contrasta il precedente esempio di Ant con un esempio di Maven. In Maven, per creare un file JAR da qualche sorgente Java, tutto quello che devi fare è creare un semplice pom.xml, mettere il tuo codice sorgente in${basedir}/src/main/java e poi eseguire mvn install dalla linea di comando. L’esempio di pom.xml di Maven che raggiunge i risultati del semplice file Ant elencato in A Simple Ant build.xml file è mostrato 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>

Questo è tutto ciò di cui hai bisogno nel tuo pom.xml. L’esecuzione di mvn install dalla linea di comando processerà le risorse, compilerà il sorgente, eseguirà gli unittest, creerà un JAR e installerà il JAR in un repository locale per riutilizzarlo in altri progetti. Senza modifiche, potete eseguire mvn sitee poi trovare un file index.html in target/site che contiene collegamenti a JavaDoc e alcuni rapporti sul vostro codice sorgente.

In effetti, questo è il progetto di esempio più semplice possibile che non contiene altro che un po’ di codice sorgente e produce un semplice JAR. È un progetto che segue da vicino le convenzioni di Maven e non richiede alcuna dipendenza o personalizzazione. Se volessimo iniziare a personalizzare il comportamento, il nostro pom.xml crescerebbe in dimensioni, e nei progetti più grandi si possono vedere collezioni di POM molto complesse che contengono una grande quantità di personalizzazione dei plugin e di dichiarazioni di dipendenze. Ma, anche quando i file POM del tuo progetto diventano più sostanziosi, contengono un tipo di informazioni completamente diverso dal file di build di un progetto di dimensioni simili che usa Ant. I POM di Maven contengono dichiarazioni: “Questo è un progetto JAR” e “Il codice sorgente è in src/main/java”. I file di build di Ant contengono istruzioni esplicite: “Questo è un progetto”, “Il sorgente è in src/main/java”, “Esegui javacainst questa directory”, “Metti i risultati in target/classes”, “Crea un JAR da ….”, ecc. Dove Ant doveva essere esplicito riguardo al processo, c’era qualcosa di “incorporato” in Maven che sapeva semplicemente dov’era il codice sorgente e come doveva essere processato.

Le differenze tra Ant e Maven in questo esempio sono:

  • Apache Ant

    • Ant non ha convenzioni formali come una struttura di directory di progetto comune o comportamenti predefiniti. Dovete dire ad Ant esattamente dove trovare il sorgente e dove mettere l’output. Convenzioni informali sono emerse nel tempo, ma non sono state codificate nel prodotto.
    • Ant è procedurale. Dovete dire ad Ant esattamente cosa fare e quando farlo. Devi dirgli di compilare, poi copiare, poi comprimere.
    • Ant non ha un ciclo di vita. Devi definire obiettivi e dipendenze di obiettivi. Devi allegare una sequenza di compiti ad ogni obiettivo manualmente.
  • Apache Maven

    • Maven ha convenzioni. Sa dov’è il tuo codice sorgente perché hai seguito la convenzione. Il plugin compilatore di Maven mette il bytecode in target/classes, e produce un file JAR in target.
    • Maven è dichiarativo. Tutto quello che dovevi fare era creare un file pom.xml e mettere il tuo sorgente nella directory di default. Maven si è occupato del resto.
    • Maven ha un ciclo di vita che è stato invocato quando hai eseguito mvn install. Questo comando ha detto a Maven di eseguire una serie di fasi sequenziali del ciclo di vita fino a raggiungere la fase del ciclo di vita di installazione. Come effetto collaterale di questo viaggio attraverso il ciclo di vita, Maven ha eseguito un certo numero di obiettivi di plugin predefiniti che hanno fatto cose come compilare e creare un JAR.

Maven ha un’intelligenza incorporata sui comuni compiti del progetto nella forma di plugin Maven. Se volete scrivere ed eseguire test unitari, tutto quello che dovete fare è scrivere i test, metterli in${basedir}/src/test/java, aggiungere una dipendenza test-scoped o TestNG o JUnit, ed eseguire mvn test. Se si volesse distribuire un’applicazione web e non un JAR, tutto quello che si dovrebbe fare è cambiare il tipo di progetto in war e mettere la docroot in${basedir}/src/main/webapp. Certo, potete fare tutto questo con Ant, ma dovrete scrivere le istruzioni da zero. In Ant, dovreste prima capire dove dovrebbe essere il file JUnit JAR. Poi dovreste creare un classpath che includa il file JUnitJAR. Poi dovresti dire ad Ant dove dovrebbe cercare il codice sorgente dei test, scrivere un obiettivo che compili il sorgente dei test in bytecode, ed eseguire i test unitari con JUnit.

Senza tecnologie di supporto come antlibs e Ivy (anche con queste tecnologie di supporto), Ant ha la sensazione di un proceduralbuild personalizzato. Un efficiente insieme di POM di Maven in un progetto che aderisce alle convenzioni assunte da Maven ha sorprendentemente poco XML rispetto all’alternativa Ant. Un altro vantaggio di Maven è la dipendenza da plugin Maven largamente condivisi. Tutti usano il plugin Surefire di Maven per i test unitari, e se qualcuno aggiunge il supporto per un nuovo framework di test unitari, puoi ottenere nuove capacità nella tua build semplicemente aumentando la versione di un particolare plugin di Maven nel POM del tuo progetto.

La decisione di usare Maven o Ant non è binaria, e Ant ha ancora un posto in una build complessa. Se la tua build attuale contiene qualche processo altamente personalizzato, o se hai scritto alcuni script Ant per completare un processo specifico in un modo specifico che non può essere adattato agli standard di Maven, puoi ancora usare questi script con Maven. Ant è reso disponibile come plugin Maven di base. I plugin Maven personalizzati possono essere implementati in Ant, e i progetti Maven possono essere configurati per eseguire gli script Ant all’interno del ciclo di vita del progetto Maven.

Leave a Reply