Alguém poderia me dizer as diferenças entre Ant e Maven? Eu também nunca usei. Entendo que eles são usados para automatizar a construção de projetos Java, mas não sei por onde começar.
Alguém poderia me dizer as diferenças entre Ant e Maven? Eu também nunca usei. Entendo que eles são usados para automatizar a construção de projetos Java, mas não sei por onde começar.
Respostas:
No Maven: The Definitive Guide , escrevi sobre as diferenças entre Maven e Ant. Na introdução, o título da seção é "As diferenças entre Ant e Maven" . Aqui está uma resposta que é uma combinação das informações nessa introdução com algumas notas adicionais.
Uma comparação simples
Estou apenas mostrando isso para ilustrar a idéia de que, no nível mais básico, o Maven tem convenções internas. Aqui está um simples arquivo de construção do 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>
Neste exemplo simples do Ant, você pode ver como precisa dizer ao Ant exatamente o que fazer. Há um objetivo de compilação que inclui a tarefa javac que compila a fonte no diretório src / main / java para o diretório target / classes. Você precisa informar ao Ant exatamente onde está sua fonte, onde deseja que o bytecode resultante seja armazenado e como compactar tudo isso em um arquivo JAR. Embora existam desenvolvimentos recentes que ajudem a tornar o Ant menos procedural, a experiência de um desenvolvedor com Ant está na codificação de uma linguagem processual escrita em XML.
Compare o exemplo anterior do Ant com o exemplo do Maven. No Maven, para criar um arquivo JAR a partir de alguma fonte Java, tudo o que você precisa fazer é criar um pom.xml simples, colocar seu código-fonte em $ {basedir} / src / main / java e executar o mvn install a partir da linha de comando . O exemplo Maven pom.xml que obtém os mesmos resultados.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>my-project</artifactId>
<version>1.0</version>
</project>
É tudo o que você precisa no seu pom.xml. A execução do mvn install a partir da linha de comandos processará recursos, compilará a origem, executará testes de unidade, criará um JAR e instalará o JAR em um repositório local para reutilização em outros projetos. Sem modificação, você pode executar o site mvn e, em seguida, encontrar um arquivo index.html no destino / site que contém links para JavaDoc e alguns relatórios sobre seu código-fonte.
É certo que este é o exemplo de projeto mais simples possível. Um projeto que contém apenas código fonte e que produz um JAR. Um projeto que segue as convenções do Maven e não requer nenhuma dependência ou personalização. Se quisermos começar a personalizar o comportamento, nosso pom.xml aumentará de tamanho e, no maior dos projetos, você poderá ver coleções de POMs Maven muito complexas que contêm uma grande quantidade de personalização de plug-in e declarações de dependência. Mas, mesmo quando os arquivos POM do seu projeto se tornam mais substanciais, eles mantêm um tipo de informação totalmente diferente do arquivo de compilação de um projeto de tamanho semelhante usando o Ant. POMs Maven contêm declarações: "Este é um projeto JAR" e "O código fonte está em src / main / java". Os arquivos de compilação da formiga contêm instruções explícitas: "This is project", "src/main/java
"," Executar javac
neste diretório "," Colocar os resultados em target/classses
"," Criar um JAR a partir do .... ", etc. Onde o Ant precisava ser explícito sobre o processo, havia algo" interno "no Maven que apenas sabia onde estava o código fonte e como deveria ser processado.
Comparação de alto nível
As diferenças entre Ant e Maven neste exemplo? Formiga...
Onde Maven ...
mvn install
. Este comando disse ao Maven para executar uma série de etapas de sequência até atingir o ciclo de vida. Como efeito colateral dessa jornada no ciclo de vida, o Maven executou vários objetivos de plug-in padrão que fizeram coisas como compilar e criar um JAR.E a Ivy?
Certo, alguém como Steve Loughran vai ler essa comparação e chamar falta. Ele vai falar sobre como a resposta ignora completamente algo chamado Ivy e o fato de o Ant poder reutilizar a lógica de construção nas versões mais recentes do Ant. Isso é verdade. Se você tem um monte de pessoas inteligentes usando Ant + antlibs + Ivy, terá uma compilação bem projetada que funciona. Mesmo assim, estou muito convencido de que o Maven faz sentido. Eu usaria felizmente o Ant + Ivy com uma equipe de projeto que tinha um engenheiro de construção muito afiado. Dito isto, acho que você acabará perdendo vários plugins valiosos, como o plugin Jetty, e que acabará fazendo um monte de trabalho que não precisou fazer com o tempo.
Mais importante que Maven vs. Ant
Maven é uma estrutura, Ant é uma caixa de ferramentas
O Maven é um carro pré-fabricado, enquanto o Ant é um conjunto de peças. Com o Ant, você precisa montar seu próprio carro, mas pelo menos se precisar dirigir fora de estrada, pode construir o tipo certo de carro.
Em outras palavras, o Maven é uma estrutura, enquanto o Ant é uma caixa de ferramentas. Se você estiver satisfeito com o trabalho dentro dos limites da estrutura, o Maven se sairá bem. O problema para mim era que eu continuava esbarrando nos limites da estrutura e isso não me deixava sair.
Verbosidade XML
tobrien é um cara que sabe muito sobre Maven e acho que ele forneceu uma comparação muito boa e honesta dos dois produtos. Ele comparou um simples pom.xml do Maven com um arquivo simples de compilação do Ant e mencionou como os projetos do Maven podem se tornar mais complexos. Eu acho que vale a pena dar uma olhada em uma comparação de alguns arquivos que você provavelmente verá em um projeto simples do mundo real. Os arquivos abaixo representam um único módulo em uma compilação de vários módulos.
Primeiro, o arquivo 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 o arquivo 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 usou seu exemplo para mostrar que o Maven possui convenções internas, mas isso não significa necessariamente que você acaba escrevendo menos XML. Eu achei o oposto verdadeiro. O pom.xml é três vezes mais longo que o build.xml e isso não se afasta das convenções. De fato, meu exemplo do Maven é mostrado sem 54 linhas extras necessárias para configurar plugins. Esse pom.xml é para um projeto simples. O XML realmente começa a crescer significativamente quando você começa a adicionar requisitos extras, o que não é incomum para muitos projetos.
Mas você precisa dizer ao Ant o que fazer
Meu exemplo do Ant acima não está completo, é claro. Ainda precisamos definir os destinos usados para limpar, compilar, testar etc. Eles são definidos em um arquivo de compilação comum que é importado por todos os módulos no projeto de múltiplos módulos. O que me leva ao ponto de como todas essas coisas devem ser explicitamente escritas no Ant, enquanto são declarativas no Maven.
É verdade, me pouparia tempo se eu não tivesse que escrever explicitamente esses destinos Ant. Mas quanto tempo? O arquivo de compilação comum que eu uso agora é o que escrevi há 5 anos, com apenas alguns refinamentos desde então. Após meus 2 anos de experiência com o Maven, retirei o arquivo antigo de construção do Ant, tirei o pó e coloquei de volta no trabalho. Para mim, o custo de ter que dizer explicitamente a Ant o que fazer aumentou em menos de uma semana em um período de 5 anos.
Complexidade
A próxima grande diferença que eu gostaria de mencionar é a da complexidade e o efeito do mundo real que ela tem. O Maven foi criado com a intenção de reduzir a carga de trabalho de desenvolvedores encarregados de criar e gerenciar processos de compilação. Para fazer isso, tem que ser complexo. Infelizmente essa complexidade tende a negar o objetivo pretendido.
Quando comparado com o Ant, o desenvolvedor do projeto Maven gasta mais tempo:
Em contraste:
Familiaridade
Outra diferença é a da familiaridade. Os novos desenvolvedores sempre precisam de tempo para se atualizar. A familiaridade com os produtos existentes ajuda nesse sentido e os apoiadores do Maven afirmam com razão que esse é um benefício do Maven. Obviamente, a flexibilidade do Ant significa que você pode criar as convenções que desejar. Portanto, a convenção que utilizo é colocar meus arquivos de origem em um nome de diretório src / main / java. Minhas classes compiladas vão para um diretório chamado target / classes. Parece familiar, não é?
Eu gosto da estrutura de diretórios usada pelo Maven. Eu acho que faz sentido. Também seu ciclo de vida de construção. Então, eu uso as mesmas convenções nas minhas construções do Ant. Não apenas porque faz sentido, mas porque será familiar para quem já usou o Maven antes.
pom.xml
s, eu gero a maioria deles via XSLT.
Ant é principalmente uma ferramenta de construção.
O Maven é uma ferramenta de gerenciamento de projetos e dependências (que, obviamente, também constrói seu projeto).
Ant + Ivy é uma combinação muito boa se você quiser evitar o Maven.
Apenas para listar mais algumas diferenças:
Atualizar:
Isso veio de Maven: The Definitive Guide . Desculpe, esqueci totalmente de citá-lo.
Maven ou Ant? é uma pergunta muito semelhante a esta, que deve ajudá-lo a responder suas perguntas.
O que é o Maven? no site oficial.
edit: Para um projeto novo / greenfield, eu recomendo usar o Maven: "convenção sobre configuração" economizará um tempo decente ao escrever e configurar scripts de compilação e implantação. Quando você usa ant, o script de construção tende a crescer com o tempo em comprimento e complexidade. Para projetos existentes, pode ser difícil colocar sua configuração / layout no sistema Maven.
O Maven atua como uma ferramenta de gerenciamento de dependências - pode ser usado para recuperar jars de um repositório central ou de um repositório que você configurou - e como uma ferramenta de construção declarativa. A diferença entre uma ferramenta de construção "declarativa" e uma ferramenta mais tradicional como ant ou make é que você configura o que precisa ser feito, não como ele é feito. Por exemplo, você pode dizer em um script maven que um projeto deve ser empacotado como um arquivo WAR, e o maven sabe como lidar com isso.
Maven depende de convenções sobre como os diretórios do projeto são dispostos para atingir sua "declaratividade". Por exemplo, ele possui uma convenção sobre onde colocar seu código principal, onde colocar seu web.xml, seus testes de unidade etc., mas também oferece a capacidade de alterá-los, se necessário.
Você também deve ter em mente que existe um plugin para executar comandos ant de dentro do maven:
http://maven.apache.org/plugins/maven-ant-plugin/
Além disso, os arquétipos de maven tornam muito rápido o início de um projeto. Por exemplo, existe um arquétipo do Wicket, que fornece um comando maven que você executa para obter um projeto do tipo hello world inteiro e pronto para execução.
Eu posso pegar uma pessoa que nunca viu Ant - seus build.xml
s são razoavelmente bem escritos - e eles podem entender o que está acontecendo. Posso pegar essa mesma pessoa e mostrar a ela um Maven POM e eles não têm idéia do que está acontecendo.
Em uma organização de engenharia enorme, as pessoas escrevem sobre os arquivos Ant se tornarem grandes e incontroláveis. Eu escrevi esses tipos e scripts Ant limpos. É realmente entender de antemão o que você precisa fazer daqui para frente e projetar um conjunto de modelos que possam responder a alterações e dimensionar em um período de mais de 3 anos.
A menos que você tenha um projeto simples, aprender as convenções do Maven e a maneira do Maven de fazer as coisas é um pouco de trabalho.
No final do dia, você não pode considerar um fator de inicialização do projeto com Ant ou Maven: é realmente o custo total de propriedade. O que é necessário para a organização manter e estender seu sistema de construção por alguns anos é um dos principais fatores que devem ser considerados.
Os aspectos mais importantes de um sistema de construção são gerenciamento de dependência e flexibilidade na expressão da receita de construção. Deve ser um pouco intuitivo quando bem feito.
Eu diria que depende do tamanho do seu projeto ... Pessoalmente, eu usaria o Maven para projetos simples que precisam de compilação, empacotamento e implantação simples. Assim que você precisar fazer algumas coisas mais complicadas (muitas dependências, criando arquivos de mapeamento ...), eu mudaria para o Ant ...
O Maven também abriga um grande repositório de projetos de código aberto comumente usados. Durante a construção, o Maven pode fazer o download dessas dependências para você (assim como as dependências das dependências :)) para tornar essa parte da construção de um projeto um pouco mais gerenciável.