Qualcuno potrebbe dirmi le differenze tra Ant e Maven? Non ho mai usato neanche. Capisco che sono usati per automatizzare la costruzione di progetti Java, ma non so da dove cominciare.
Qualcuno potrebbe dirmi le differenze tra Ant e Maven? Non ho mai usato neanche. Capisco che sono usati per automatizzare la costruzione di progetti Java, ma non so da dove cominciare.
Risposte:
In Maven: The Definitive Guide , ho scritto delle differenze tra Maven e Ant nell'introduzione, il titolo della sezione è "Le differenze tra Ant e Maven" . Ecco una risposta che è una combinazione delle informazioni in quell'introduzione con alcune note aggiuntive.
Un confronto semplice
Ti sto solo mostrando questo per illustrare l'idea che, al livello più elementare, Maven ha convenzioni integrate. Ecco un semplice file di build 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 di formica, puoi vedere come devi dire a Ant esattamente cosa fare. Esiste un obiettivo di compilazione che include l'attività javac che compila l'origine nella directory src / main / java nella directory target / classes. Devi dire ad Ant esattamente dove si trova la tua fonte, dove vuoi che sia memorizzato il bytecode risultante e come impacchettarlo in un file JAR. Mentre ci sono alcuni recenti sviluppi che aiutano a rendere Ant meno procedurale, l'esperienza di uno sviluppatore con Ant è nel codificare un linguaggio procedurale scritto in XML.
Contrasta il precedente esempio di formica con un esempio di Maven. In Maven, per creare un file JAR da qualche sorgente Java, tutto ciò che devi fare è creare un semplice pom.xml, posizionare il codice sorgente in $ {basedir} / src / main / java ed eseguire mvn install dalla riga di comando . L'esempio Maven pom.xml che ottiene gli stessi risultati.
<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 riga di comando elaborerà le risorse, compilerà l'origine, eseguirà i test delle unità, creerà un JAR e installerà il JAR in un repository locale per il riutilizzo in altri progetti. Senza modifiche, è possibile eseguire mvn site e quindi trovare un file index.html nella destinazione / sito che contiene collegamenti a JavaDoc e alcuni report sul codice sorgente.
Certamente, questo è il progetto di esempio più semplice possibile. Un progetto che contiene solo codice sorgente e che produce un JAR. Un progetto che segue le convenzioni di Maven e non richiede dipendenze o personalizzazioni. Se volessimo iniziare a personalizzare il comportamento, il nostro pom.xml crescerà di dimensioni e nel più grande dei progetti puoi vedere raccolte di POM Maven molto complessi che contengono molte personalizzazioni dei plugin e dichiarazioni di dipendenza. Ma anche quando i file POM del tuo progetto diventano più sostanziali, contengono un tipo di informazione completamente diverso dal file di build di un progetto di dimensioni simili che utilizza Ant. I POM Maven contengono dichiarazioni: "Questo è un progetto JAR" e "Il codice sorgente è in src / main / java". I file di build di formiche contengono istruzioni esplicite: "Questo è un progetto", "src/main/java
"," Esegui javac
contro questa directory "," Inserisci i risultati in target/classses
"," Crea un JAR dal .... ", ecc. Dove Ant doveva essere esplicito sul processo, c'era qualcosa di" incorporato "in Maven che sapeva solo dove si trovava il codice sorgente e come doveva essere elaborato.
Confronto di alto livello
Le differenze tra Ant e Maven in questo esempio? Formica...
Where Maven ...
mvn install
. Questo comando disse a Maven di eseguire una serie di passaggi di sequenza fino a raggiungere il ciclo di vita. Come effetto collaterale di questo viaggio attraverso il ciclo di vita, Maven ha eseguito una serie di obiettivi predefiniti del plug-in che hanno fatto cose come compilare e creare un JAR.E Ivy?
Bene, quindi qualcuno come Steve Loughran leggerà quel confronto e chiamerà fallo. Parlerà di come la risposta ignori completamente qualcosa chiamato Ivy e il fatto che Ant possa riutilizzare la logica di costruzione nelle versioni più recenti di Ant. Questo è vero. Se hai un sacco di persone intelligenti che usano Ant + antlibs + Ivy, finirai con una build ben progettata che funziona. Anche se, sono molto convinto che Maven abbia un senso, userei felicemente Ant + Ivy con un team di progetto che aveva un ingegnere di costruzione molto acuto. Detto questo, penso che finirai per perdere alcuni preziosi plugin come il plugin Jetty e che finirai per fare un sacco di lavoro che non hai dovuto fare nel tempo.
Più importante di Maven vs. Ant
Maven è un framework, Ant è una cassetta degli attrezzi
Maven è un'auto stradale pre-costruita, mentre Ant è un insieme di parti di automobili. Con Ant devi costruire la tua auto, ma almeno se devi fare qualsiasi guida fuoristrada puoi costruire il giusto tipo di auto.
Per dirla in altro modo, Maven è un framework mentre Ant è una cassetta degli attrezzi. Se ti accontenti di lavorare entro i limiti del framework, Maven farà bene. Il problema per me era che continuavo a sbattere contro i limiti della struttura e non mi lasciava uscire.
Verbosità XML
tobrien è un ragazzo che sa molto di Maven e penso che abbia fornito un confronto molto buono e onesto tra i due prodotti. Ha confrontato un semplice pom.xml di Maven con un semplice file di build Ant e ha fatto menzione di come i progetti Maven possano diventare più complessi. Penso che valga la pena dare un'occhiata al confronto di un paio di file che è più probabile che tu veda in un semplice progetto del mondo reale. I file seguenti rappresentano un singolo modulo in una build multi-modulo.
Innanzitutto, il file Maven:
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-4_0_0.xsd">
<parent>
<groupId>com.mycompany</groupId>
<artifactId>app-parent</artifactId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>persist</artifactId>
<name>Persistence Layer</name>
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>common</artifactId>
<scope>compile</scope>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>domain</artifactId>
<scope>provided</scope>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>${hibernate.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons-lang.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>${spring.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>2.2.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>${commons-dbcp.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc</artifactId>
<version>${oracle-jdbc.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>${easymock.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
E il file Ant equivalente:
<project name="persist" >
<import file="../build/common-build.xml" />
<path id="compile.classpath.main">
<pathelement location="${common.jar}" />
<pathelement location="${domain.jar}" />
<pathelement location="${hibernate.jar}" />
<pathelement location="${commons-lang.jar}" />
<pathelement location="${spring.jar}" />
</path>
<path id="compile.classpath.test">
<pathelement location="${classes.dir.main}" />
<pathelement location="${testng.jar}" />
<pathelement location="${dbunit.jar}" />
<pathelement location="${easymock.jar}" />
<pathelement location="${commons-dbcp.jar}" />
<pathelement location="${oracle-jdbc.jar}" />
<path refid="compile.classpath.main" />
</path>
<path id="runtime.classpath.test">
<pathelement location="${classes.dir.test}" />
<path refid="compile.classpath.test" />
</path>
</project>
tobrien ha usato il suo esempio per dimostrare che Maven ha convenzioni integrate, ma ciò non significa necessariamente che tu finisca per scrivere meno XML. Ho trovato il contrario per essere vero. Il pom.xml è 3 volte più lungo del build.xml e cioè senza allontanarsi dalle convenzioni. In effetti, il mio esempio di Maven è mostrato senza altre 54 righe necessarie per configurare i plugin. Quel pom.xml è per un semplice progetto. L'XML inizia davvero a crescere in modo significativo quando inizi ad aggiungere requisiti extra, che non è fuori dall'ordinario per molti progetti.
Ma devi dire ad Ant cosa fare
Il mio esempio di formica sopra non è completo ovviamente. Dobbiamo ancora definire gli obiettivi utilizzati per pulire, compilare, testare ecc. Questi sono definiti in un file di build comune che viene importato da tutti i moduli nel progetto multi-modulo. Il che mi porta al punto su come tutta questa roba debba essere esplicitamente scritta in Ant mentre è dichiarativa in Maven.
È vero, mi farebbe risparmiare tempo se non dovessi scrivere esplicitamente questi target di formiche. Ma quanto tempo? Il file di build comune che uso ora è quello che ho scritto 5 anni fa con solo lievi perfezionamenti da allora. Dopo il mio esperimento di 2 anni con Maven, ho estratto il vecchio file di build Ant dall'armadio, l'ho rispolverato e rimesso a posto. Per me, il costo di dover dire esplicitamente ad Ant cosa fare è aumentato a meno di una settimana per un periodo di 5 anni.
Complessità
La prossima grande differenza che vorrei menzionare è quella della complessità e dell'effetto nel mondo reale che ha. Maven è stato creato con l'intento di ridurre il carico di lavoro degli sviluppatori incaricati di creare e gestire i processi di compilazione. Per fare ciò deve essere complesso. Sfortunatamente questa complessità tende a negare l'obiettivo prefissato.
Rispetto a Ant, il ragazzo del build su un progetto Maven passerà più tempo:
In contrasto:
Familiarità
Un'altra differenza è quella della familiarità. I nuovi sviluppatori richiedono sempre tempo per essere aggiornati. La familiarità con i prodotti esistenti aiuta in tal senso e i sostenitori di Maven affermano giustamente che questo è un vantaggio di Maven. Naturalmente, la flessibilità di Ant significa che puoi creare qualunque convenzione ti piaccia. Quindi la convenzione che uso è quella di mettere i miei file sorgente in un nome di directory src / main / java. Le mie classi compilate vanno in una directory denominata target / classi. Sembra familiare no?
Mi piace la struttura di directory utilizzata da Maven. Penso che abbia senso. Anche il loro ciclo di vita della build. Quindi uso le stesse convenzioni nei miei build Ant. Non solo perché ha senso, ma perché sarà familiare a chiunque abbia già usato Maven.
pom.xml
s, ne generi la maggior parte tramite XSLT.
La formica è principalmente uno strumento di costruzione.
Maven è uno strumento di gestione dei progetti e delle dipendenze (che ovviamente costruisce anche il tuo progetto).
Ant + Ivy è una combinazione abbastanza buona se vuoi evitare Maven.
Solo per elencare alcune altre differenze:
Aggiornare:
Questo è venuto da Maven: The Definitive Guide . Scusa, ho completamente dimenticato di citarlo.
Maven o formica? è una domanda molto simile a questa, che dovrebbe aiutarti a rispondere alle tue domande.
Che cos'è Maven? sul sito ufficiale.
modifica: Per un nuovo progetto / greenfield, consiglierei di usare Maven: "convenzione sulla configurazione" ti farà risparmiare un bel po 'di tempo nella scrittura e impostazione di script di compilazione e distribuzione. Quando usi la formica, lo script di compilazione tende a crescere nel tempo in termini di lunghezza e complessità. Per i progetti esistenti, può essere difficile calzare la loro configurazione / layout nel sistema Maven.
Maven funge sia da strumento di gestione delle dipendenze - può essere utilizzato per recuperare vasetti da un repository centrale o da un repository impostato - sia come strumento di compilazione dichiarativo. La differenza tra uno strumento di costruzione "dichiarativo" e uno più tradizionale come ant o make è che si configura ciò che deve essere fatto, non come viene fatto. Ad esempio, puoi dire in uno script di Maven che un progetto deve essere impacchettato come file WAR e Maven sa come gestirlo.
Maven si affida alle convenzioni su come sono disposte le directory del progetto per raggiungere la sua "dichiaratività". Ad esempio, ha una convenzione su dove inserire il codice principale, dove inserire web.xml, i test delle unità e così via, ma offre anche la possibilità di cambiarli se necessario.
Dovresti anche tenere presente che esiste un plug-in per l'esecuzione dei comandi ant all'interno di Maven:
http://maven.apache.org/plugins/maven-ant-plugin/
Inoltre, gli archetipi di Maven rendono molto veloce l'avvio di un progetto. Ad esempio, esiste un archetipo Wicket, che fornisce un comando maven eseguito per ottenere un intero progetto di tipo mondiale pronto per l'esecuzione.
Posso prendere una persona che non ha mai visto la formica - i suoi build.xml
sono ragionevolmente ben scritti - e possono capire cosa sta succedendo. Posso prendere quella stessa persona e mostrare loro un Maven POM e non avranno idea di cosa stia succedendo.
In un'organizzazione di ingegneria che è enorme, le persone scrivono che i file Ant diventano grandi e ingestibili. Ho scritto quei tipi e gli script Ant puliti. Comprende davvero in anticipo ciò che è necessario fare per andare avanti e progettare una serie di modelli in grado di rispondere ai cambiamenti e alle dimensioni in un periodo di oltre 3 anni.
A meno che tu non abbia un semplice progetto, imparare le convenzioni di Maven e il modo di Maven di fare le cose è un bel po 'di lavoro.
Alla fine della giornata non puoi considerare l'avvio di un progetto con Ant o Maven un fattore: è davvero il costo totale di proprietà. Ciò che serve all'organizzazione per mantenere ed estendere il suo sistema di build per alcuni anni è uno dei principali fattori che devono essere considerati.
Gli aspetti più importanti di un sistema di build sono la gestione delle dipendenze e la flessibilità nell'esprimere la ricetta di build. Deve essere in qualche modo intuitivo se fatto bene.
Direi che dipende dalle dimensioni del tuo progetto ... Personalmente, userei Maven per progetti semplici che necessitano di compilazione, packaging e distribuzione semplici. Non appena devi fare alcune cose più complicate (molte dipendenze, creare file di mappatura ...), passerei ad Ant ...
Maven ospita anche un ampio repository di progetti open source comunemente utilizzati. Durante la compilazione Maven può scaricare queste dipendenze per te (così come le tue dipendenze :)) per rendere questa parte della costruzione di un progetto un po 'più gestibile.