Czy ktoś mógłby mi powiedzieć różnice między Ant i Maven? Nigdy też nie użyłem. Rozumiem, że służą one do automatyzacji budowy projektów Java, ale nie wiem od czego zacząć.
Czy ktoś mógłby mi powiedzieć różnice między Ant i Maven? Nigdy też nie użyłem. Rozumiem, że służą one do automatyzacji budowy projektów Java, ale nie wiem od czego zacząć.
Odpowiedzi:
W Maven: The Definitive Guide napisałem o różnicach między Maven a Antem we wstępie, tytuł sekcji to „Różnice między Ant a Maven” . Oto odpowiedź będąca połączeniem informacji zawartych we wstępie z dodatkowymi uwagami.
Proste porównanie
Pokazuję to tylko dla zilustrowania idei, że na najbardziej podstawowym poziomie Maven ma wbudowane konwencje. Oto prosty plik kompilacji 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 Anta możesz zobaczyć, jak musisz powiedzieć Antowi dokładnie, co ma robić. Istnieje cel kompilacji, który obejmuje zadanie javac, które kompiluje źródło w katalogu src / main / java do katalogu docelowego / klas. Musisz powiedzieć Antowi dokładnie, gdzie jest twoje źródło, gdzie chcesz zapisać wynikowy kod bajtowy i jak spakować to wszystko do pliku JAR. Chociaż ostatnio pojawiły się pewne zmiany, które sprawiają, że Ant jest mniej proceduralny, doświadczenie programisty z Antem polega na kodowaniu języka proceduralnego napisanego w XML.
Porównaj poprzedni przykład Mrówki z przykładem Mavena. W Maven, aby utworzyć plik JAR z jakiegoś źródła Java, wystarczy utworzyć prosty plik pom.xml, umieścić kod źródłowy w $ {basedir} / src / main / java, a następnie uruchomić mvn install z wiersza poleceń . Przykład Maven pom.xml, który osiąga te same wyniki.
<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 pliku pom.xml. Uruchomienie instalacji mvn z wiersza polecenia spowoduje przetworzenie zasobów, skompilowanie źródła, wykonanie testów jednostkowych, utworzenie pliku JAR i zainstalowanie pliku JAR w lokalnym repozytorium w celu ponownego wykorzystania w innych projektach. Bez modyfikacji możesz uruchomić mvn site, a następnie znaleźć plik index.html w target / site, który zawiera linki do JavaDoc i kilka raportów o twoim kodzie źródłowym.
Trzeba przyznać, że jest to najprostszy możliwy przykładowy projekt. Projekt, który zawiera tylko kod źródłowy i który tworzy plik JAR. Projekt zgodny z konwencjami Mavena i nie wymagający żadnych zależności ani dostosowywania. Jeśli chcielibyśmy zacząć dostosowywać zachowanie, nasz plik pom.xml będzie się powiększał, aw największych projektach można zobaczyć kolekcje bardzo złożonych POM Maven, które zawierają wiele dostosowań wtyczek i deklaracji zależności. Ale nawet gdy pliki POM twojego projektu stają się bardziej znaczące, przechowują one zupełnie inny rodzaj informacji niż plik kompilacji projektu o podobnej wielkości przy użyciu Anta. POM Maven zawiera deklaracje: „To jest projekt JAR” i „Kod źródłowy znajduje się w src / main / java”. Pliki kompilacji mrówek zawierają wyraźne instrukcje: „To jest projekt”, „src/main/java
”,„ Uruchom javac
z tego katalogu ”,„ Umieść wyniki w target/classses
”,„ Utwórz plik JAR z… ”itp. W przypadku Anta trzeba było wyraźnie powiedzieć o tym procesie, w Maven było coś„ wbudowanego ” po prostu wiedział, gdzie jest kod źródłowy i jak powinien zostać przetworzony.
Porównanie na wysokim poziomie
Różnice między Ant i Maven w tym przykładzie? Mrówka...
Gdzie Maven ...
mvn install
. To polecenie kazało Mavenowi wykonać serię kroków sekwencji, dopóki nie osiągnie cyklu życia. Jako efekt uboczny tej podróży przez cykl życia, Maven wykonał szereg domyślnych celów wtyczek, które polegały na kompilacji i utworzeniu pliku JAR.Co z Ivy?
Zgadza się, więc ktoś taki jak Steve Loughran przeczyta to porównanie i ogłosi faul. Będzie mówił o tym, jak odpowiedź całkowicie ignoruje coś o nazwie Ivy oraz o tym, że Ant może ponownie użyć logiki kompilacji w nowszych wersjach Anta. To prawda. Jeśli masz grupę inteligentnych ludzi używających Ant + Antlibs + Ivy, skończysz z dobrze zaprojektowaną kompilacją, która działa. Chociaż jestem bardzo przekonany, że Maven ma sens, chętnie skorzystam z Ant + Ivy z zespołem projektowym, który ma bardzo bystrego inżyniera budowy. Biorąc to pod uwagę, myślę, że w końcu stracisz wiele cennych wtyczek, takich jak wtyczka Jetty, i że wykonasz całą pracę, której z czasem nie musiałeś wykonywać.
Ważniejsze niż Maven vs. Ant
Maven to Framework, Ant to Toolbox
Maven to fabrycznie zbudowany samochód drogowy, a Ant to zestaw części samochodowych. Z Antem musisz zbudować własny samochód, ale przynajmniej jeśli chcesz jeździć w terenie, możesz zbudować odpowiedni rodzaj samochodu.
Innymi słowy, Maven to framework, a Ant to zestaw narzędzi. Jeśli jesteś zadowolony z pracy w ramach frameworka, Maven będzie w porządku. Problemem było to, że ciągle wpadałem na granice frameworka i nie wypuściło mnie to.
Szczegółowość XML
tobrien jest facetem, który dużo wie o Maven i myślę, że zapewnił bardzo dobre, uczciwe porównanie tych dwóch produktów. Porównał prosty Maven pom.xml z prostym plikiem kompilacji Anta i wspomniał o tym, jak projekty Maven mogą stać się bardziej złożone. Myślę, że warto spojrzeć na porównanie kilku plików, które są bardziej prawdopodobne w prostym projekcie z prawdziwego świata. Poniższe pliki reprezentują pojedynczy moduł w wersji wielomodułowej.
Po pierwsze, plik 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>
I równoważny plik Ant:
<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 wykorzystał swój przykład, aby pokazać, że Maven ma wbudowane konwencje, ale to niekoniecznie oznacza, że w końcu piszesz mniej XML. Uważam, że jest odwrotnie. Plik pom.xml jest 3 razy dłuższy niż plik build.xml i to bez odchodzenia od konwencji. W rzeczywistości mój przykład Maven jest pokazany bez dodatkowych 54 linii wymaganych do skonfigurowania wtyczek. Ten plik pom.xml jest przeznaczony do prostego projektu. XML naprawdę zaczyna rosnąć, gdy zaczynasz dodawać dodatkowe wymagania, co nie jest niczym niezwykłym w wielu projektach.
Ale musisz powiedzieć Antowi, co ma robić
Powyższy przykład mrówki nie jest oczywiście kompletny. Nadal musimy zdefiniować cele używane do czyszczenia, kompilacji, testowania itp. Są one zdefiniowane we wspólnym pliku kompilacji, który jest importowany przez wszystkie moduły w projekcie wielomodułowym. Co prowadzi mnie do tego, że wszystkie te rzeczy muszą być wyraźnie napisane w Ant, podczas gdy w Maven jest deklaratywne.
To prawda, że zaoszczędziłbym czas, gdybym nie musiał wyraźnie pisać tych celów Ant. Ale ile czasu? Wspólny plik kompilacji, którego teraz używam, to taki, który napisałem 5 lat temu, od tego czasu tylko nieznacznie dopracowując. Po 2-letnim eksperymencie z Mavenem wyciągnąłem z szafy stary plik kompilacji Anta, odkurzyłem go i przywróciłem do pracy. Dla mnie koszt konieczności wyraźnego powiedzenia Antowi, co należy zrobić, wyniósł mniej niż tydzień w ciągu 5 lat.
Złożoność
Kolejną znaczącą różnicą, o której chciałbym wspomnieć, jest złożoność i rzeczywisty efekt, jaki ma. Maven został zbudowany z myślą o zmniejszeniu obciążenia programistów odpowiedzialnych za tworzenie i zarządzanie procesami kompilacji. Aby to zrobić, musi być złożony. Niestety ta złożoność ma tendencję do negowania zamierzonego celu.
W porównaniu z Antem facet z kompilacji w projekcie Maven poświęci więcej czasu:
W przeciwieństwie:
Znajomość
Kolejną różnicą jest znajomość. Nowi programiści zawsze potrzebują czasu, aby przyśpieszyć. Znajomość istniejących produktów pomaga w tym względzie, a zwolennicy Maven słusznie twierdzą, że jest to korzyść Maven. Oczywiście elastyczność Anta oznacza, że możesz tworzyć dowolne konwencje. Więc konwencja, której używam, polega na umieszczeniu moich plików źródłowych w nazwie katalogu src / main / java. Moje skompilowane klasy przechodzą do katalogu o nazwie target / class. Brzmi znajomo, prawda?
Podoba mi się struktura katalogów używana przez Maven. Myślę, że to ma sens. Również ich cykl życia. Dlatego używam tych samych konwencji w moich kompilacjach Ant. Nie tylko dlatego, że ma to sens, ale dlatego, że będzie znany każdemu, kto wcześniej korzystał z Maven.
pom.xml
, generuję większość z nich poprzez XSLT.
Ant jest głównie narzędziem do budowania.
Maven to narzędzie do zarządzania projektami i zależnościami (które oczywiście również tworzy Twój projekt).
Ant + Ivy to całkiem niezła kombinacja, jeśli chcesz uniknąć Maven.
Wystarczy wymienić jeszcze kilka różnic:
Aktualizacja:
To pochodzi z Maven: The Definitive Guide . Przepraszam, całkowicie zapomniałem to zacytować.
Maven czy Ant? jest bardzo podobnym pytaniem do tego, które powinno pomóc ci odpowiedzieć na twoje pytania.
Co to jest Maven? na oficjalnej stronie.
edycja: W przypadku nowego projektu / greenfield polecam użycie Maven: „konwencja nad konfiguracją” pozwoli zaoszczędzić sporo czasu na pisanie i konfigurowanie skryptów kompilacji i wdrażania. Kiedy używasz mrówki, skrypt kompilacji ma tendencję do powiększania się wraz z upływem czasu i złożonością. W przypadku istniejących projektów może być trudno sprawdzić ich konfigurację / układ w systemie Maven.
Maven działa zarówno jako narzędzie do zarządzania zależnościami - może być używane do pobierania słoików z centralnego repozytorium lub z utworzonego repozytorium - oraz jako deklaratywne narzędzie do budowania. Różnica między „deklaratywnym” narzędziem do budowania a bardziej tradycyjnym, takim jak mrówka lub marka, polega na tym, że konfigurujesz to, co trzeba zrobić, a nie sposób. Na przykład możesz powiedzieć w skrypcie maven, że projekt powinien być spakowany jako plik WAR, a maven wie, jak sobie z tym poradzić.
Maven opiera się na konwencjach dotyczących sposobu tworzenia katalogów projektów, aby osiągnąć „deklaratywność”. Na przykład ma konwencję, gdzie umieścić główny kod, gdzie umieścić plik web.xml, testy jednostkowe itp., Ale daje także możliwość ich zmiany, jeśli zajdzie taka potrzeba.
Należy również pamiętać, że istnieje wtyczka do uruchamiania poleceń mrówek z poziomu maven:
http://maven.apache.org/plugins/maven-ant-plugin/
Ponadto archetypy maven sprawiają, że rozpoczęcie projektu jest naprawdę szybkie. Na przykład istnieje archetyp Wicket, który zapewnia polecenie maven, które uruchamiasz, aby uzyskać cały, gotowy do uruchomienia projekt typu witaj na świecie.
Mogę zabrać osobę, która nigdy nie widziała Anta - jego build.xml
napisy są dość dobrze napisane - i mogą zrozumieć, co się dzieje. Mogę wziąć tę samą osobę i pokazać im POM Maven, a oni nie będą mieli pojęcia, co się dzieje.
W ogromnej organizacji inżynierskiej ludzie piszą, że pliki Ant stają się duże i nie można nimi zarządzać. Napisałem te typy i czyste skrypty Ant. To naprawdę zrozumienie z góry, co musisz zrobić, i zaprojektowanie zestawu szablonów, które mogą reagować na zmiany i skalować przez ponad 3 lata.
O ile nie masz prostego projektu, poznanie konwencji Mavena i sposobu Mavena na robienie rzeczy jest dość pracochłonne.
Na koniec dnia nie można brać pod uwagę uruchomienia projektu w Ant lub Maven: to naprawdę całkowity koszt posiadania. To, czego organizacja potrzebuje do utrzymania i rozszerzenia swojego systemu kompilacji przez kilka lat, jest jednym z głównych czynników, które należy wziąć pod uwagę.
Najważniejsze aspekty systemu kompilacji to zarządzanie zależnościami i elastyczność w wyrażaniu receptury kompilacji. Dobrze wykonane musi być nieco intuicyjne.
Powiedziałbym, że zależy to od wielkości twojego projektu ... Osobiście użyłbym Maven do prostych projektów, które wymagają prostej kompilacji, pakowania i wdrożenia. Gdy tylko zajdzie potrzeba wykonania bardziej skomplikowanych czynności (wiele zależności, tworzenie plików mapowania ...), przełączę się na Ant ...
W Maven znajduje się również duże repozytorium często używanych projektów open source. Podczas kompilacji Maven może pobrać te zależności (a także zależności zależności :)), aby ta część budowania projektu była nieco łatwiejsza do zarządzania.