TheNEXUS

1.7. Porównanie Mavena z Antem

Autorzy tej książki nie mają żadnego interesu w tworzeniu waśni pomiędzy Apache Ant i Apache Mavenem, ale jesteśmy również świadomi faktu, że większość organizacji musi podjąć decyzję pomiędzy dwoma standardowymi rozwiązaniami: Apache Ant i Apache Maven. W tej sekcji porównamy i zestawimy te narzędzia.

Ant wyróżnia się w procesie budowania, jest to system budowania wzorowany na makewith z celami i zależnościami. Każdy cel składa się z zestawu instrukcji, które są zakodowane w XML. Istnieje zadanie copy oraz zadaniejavac, jak również zadanie jar. Kiedy używasz Anta, dostarczasz mu specyficzne instrukcje dotyczące kompilacji i pakowania twoich danych wyjściowych. Spójrz na poniższy przykład prostego pliku build.xml:

Prosty plik build.xml 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>

W tym prostym przykładzie Ant, możesz zobaczyć jak musisz powiedzieć Antexact dokładnie co ma robić. Istnieje cel kompilacji, który zawiera javaczadanie, które kompiluje źródło w katalogu src/main/java do katalogu thetarget/classes. Musisz powiedzieć Antowi, gdzie dokładnie znajduje się twoje źródło, gdzie chcesz, aby wynikowy kod bajtowy był przechowywany i jak zapakować to wszystko do pliku JAR. Podczas gdy istnieją pewne ostatnie opracowania, które pomagają uczynić Ant mniej proceduralnym, doświadczenie programisty z Ant polega na kodowaniu języka proceduralnego napisanego w XML.

Porównaj poprzedni przykład Ant z przykładem Maven. W Maven, aby utworzyć plik JAR z jakiegoś źródła Java, wystarczy utworzyć prosty pom.xml, umieścić swój kod źródłowy w ${basedir}/src/main/java, a następnie uruchomić mvn install z linii poleceń. Przykładowy plik Maven pom.xml, który osiąga takie same wyniki jak prosty plik Ant wymieniony w A Simple Ant build.xml file, jest pokazany wA 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>

To wszystko, czego potrzebujesz w swoim pom.xml. Uruchomienie mvn install z linii poleceń przetworzy zasoby, skompiluje źródło, wykona unittesty, utworzy JAR i zainstaluje JAR w lokalnym repozytorium do ponownego użycia w innych projektach. Bez modyfikacji, możesz uruchomić mvn site i znaleźć plik index.html w target/site, który zawiera odnośniki do JavaDoc i kilka raportów o twoim kodzie źródłowym.

Przyznać trzeba, że jest to najprostszy możliwy projekt przykładowy, zawierający nic więcej niż trochę kodu źródłowego i produkujący prosty JAR. Jest to projekt, który ściśle trzyma się konwencji Mavena i nie wymaga żadnych zależności ani dostosowywania. Jeśli chcielibyśmy zacząć dostosowywać nasze zachowanie, nasz pom.xml będzie miał coraz większe rozmiary, a w największych projektach można zobaczyć kolekcje bardzo złożonych POM-ów Mavena, które zawierają ogromną ilość wtyczek i deklaracji zależności. Ale nawet gdy pliki POM Twojego projektu stają się bardziej obszerne, zawierają one zupełnie inny rodzaj informacji niż plik budujący podobnej wielkości projekt wykorzystujący Ant. Maven POM zawiera deklaracje: „To jest projekt JAR”, oraz „Kod źródłowy znajduje się w src/main/java”. Pliki kompilacji Ant zawierają wyraźne instrukcje: „This is project”, „The source is in src/main/java”, „Run javacagainst this directory”, „Put the results in target/classes”, „Create a JAR from the ….”, etc. Tam, gdzie Ant musiał wyraźnie określić proces, było coś „wbudowanego” w Mavena, który po prostu wiedział, gdzie znajduje się kod źródłowy i jak powinien być przetwarzany.

Różnice między Ant i Maven w tym przykładzie są następujące:

  • Apache Ant

    • Ant nie ma formalnych konwencji, takich jak wspólna struktura katalogów projektu lub domyślne zachowanie. Musisz dokładnie powiedzieć Antowi gdzie ma znaleźć źródło i gdzie umieścić dane wyjściowe. Nieformalne konwencje pojawiły się z czasem, ale nie zostały skodyfikowane w produkcie.
    • Ant jest proceduralny. Musisz powiedzieć Antowi dokładnie co i kiedy ma robić. Musisz powiedzieć mu, aby skompilował, następnie skopiował, a następnie skompresował.
    • Ant nie ma cyklu życia. Musisz zdefiniować cele i zależności od celów. Musisz ręcznie dołączyć sekwencję zadań do każdego celu.
  • Apache Maven

    • Maven ma konwencje. Wie, gdzie jest twój kod źródłowy, ponieważ podążałeś za konwencją. Wtyczka kompilatora Mavena umieściła kod bajtowy w target/classes, a to produkuje plik JAR w target.
    • Maven jest deklaratywny. Wszystko, co musiałeś zrobić, to utworzyć plik pom.xml i umieścić swoje źródło w domyślnym katalogu. Maven zajął się resztą.
    • Maven ma cykl życia, który został wywołany, gdy wykonałeś mvn install. To polecenie powiedziało Mavenowi, aby wykonał serię sekwencyjnych faz cyklu życia, aż dotarł do fazy cyklu życia instalacji. Jako efekt uboczny tej podróży przez cykl życia, Maven wykonał wiele domyślnych celów wtyczek, które robiły takie rzeczy jak kompilacja i tworzenie JAR.

Maven ma wbudowaną inteligencję na temat typowych zadań projektu w postaci wtyczek Maven. Jeśli chciałbyś napisać i wykonać testy jednostkowe, musiałbyś jedynie napisać testy, umieścić je w ${basedir}/src/test/java, dodać zależność TestNG lub JUnit i uruchomić mvn test. Jeśli chciałbyś wdrożyć aplikację webową, a nie JAR, wszystko co musiałbyś zrobić to zmienić typ projektu na war i umieścić swój docroot w ${basedir}/src/main/webapp. Oczywiście, możesz to wszystko zrobić za pomocą Anta, ale będziesz musiał pisać instrukcje od zera. W Ant, musiałbyś najpierw dowiedzieć się, gdzie powinien znajdować się plik JUnit JAR. Następnie musiałbyś utworzyć ścieżkę klas, która zawiera plik JUnitJAR. Następnie powiedziałbyś Ant, gdzie powinna szukać kodu źródłowego testu, napisać cel, który kompiluje źródło testu do kodu bajtowego, i wykonać testy jednostkowe za pomocą JUnit.

Bez technologii wspierających, takich jak antlibs i Ivy (nawet z tymi technologiami), Ant ma poczucie niestandardowego proceduralbuild. Wydajny zestaw Maven POMs w projekcie, który trzyma się założonych konwencji Mavena ma zaskakująco mało XML w porównaniu do alternatywy Ant. Kolejną zaletą Mavena jest oparcie się na szeroko rozpowszechnionych wtyczkach Mavena. Każdy używa wtyczki Maven Surefire do testów jednostkowych, a jeśli ktoś doda wsparcie dla nowej struktury testów jednostkowych, możesz zyskać nowe możliwości w swoim własnym kompilatorze po prostu zwiększając wersję konkretnej wtyczki Mavena w POM projektu.

Decyzja o użyciu Mavena lub Anta nie jest binarna, a Ant wciąż ma swoje miejsce w złożonym kompilatorze. Jeśli twoja bieżąca kompilacja zawiera jakiś wysoce niestandardowy proces, lub jeśli napisałeś kilka skryptów Anta, aby zakończyć specyficzny proces w specyficzny sposób, który nie może być dostosowany do standardów Mavena, możesz nadal używać tych skryptów z Mavenem. Ant jest udostępniany jako podstawowy plugin Mavena. Niestandardowe wtyczki Mavena mogą być zaimplementowane w Ant, a projekty Mavena mogą być skonfigurowane do wykonywania skryptów Ant w ramach cyklu życia projektu Maven.

Leave a Reply