Processo de build com o Maven
Postado em 07. jul, 2008 por Lucas Cavalcanti em Inovação
O Maven é uma ferramenta de gerenciamento, construção e implantação de projetos muito interessante, que te ajuda no processo de gerenciamento de dependências e no de build, geração de relatórios e de documentação. Na Caelum esta é a ferramenta usada em todos os projetos internos e nas consultorias.
Muitas pessoas migram seus projetos para o Maven, mas acabam arrumando mais problemas que soluções, pois não conseguem configurá-lo corretamente, e acabam desistindo e fazendo tudo na mão, ou voltando para o Ant. Mas se você conseguir ajustar as configurações, o Maven vai te ajudar muito e vai compensar todos os (poucos) problemas que ele eventualmente causa. No início do uso do Maven, espere formar com ele uma relação de amor e ódio.
Para começar a usar o Maven, tudo o que você precisa fazer é baixá-lo e configurar umas poucas variáveis de ambiente. Depois de ter feito isso, é só digitar mvn [target] na linha de comando. Alguns sistemas operacionais já te oferecem essa instalação através do macport ou apt-get.
A unidade básica de configuração do Maven é um arquivo chamado pom.xml, que deve ficar na raiz do seu projeto. Ele é um arquivo conhecido como Project Object Model: lá você declara a estrutura, dependências e características do seu projeto. A idéia é bem parecida com o build.xml do Ant: você deixa o pom.xml na raiz do seu projeto para poder chamar as targets de build do seu projeto. O menor arquivo pom.xml válido é o seguinte:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>br.com.caelum</groupId>
<artifactId>teste</artifactId>
<version>1.0</version>
</project>
Que contém apenas a identificação do projeto, e uma informação a mais: modelVersion, que é a identificação da versão do arquivo pom.xml e deve ser sempre 4.0.0. A identificação do projeto consiste em três informações:
groupId: um identificador da empresa/grupo ao qual o projeto pertence. Geralmente o nome do site da empresa/grupo ao contrário. Ex:br.com.caelum.artifactId: o nome do projeto. Ex:teste.version: a versão atual do projeto. Ex:1.0-SNAPSHOT.
Essas informações são usadas em muitos lugares, ccomo o controle de dependências que é, na minha opinião, a funcionalidade mais útil do Maven. Por exemplo, para dizer que o log4j 1.2.15 é uma dependência da sua aplicação é só acrescentar no seu pom as linhas:
<project>
...
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
</dependency>
</dependencies>
...
</project>
Quando necessário, o Maven vai baixar pra você o jar do log4j 1.2.15, e todas as suas dependências, e vai colocá-las no classpath da sua aplicação durante os builds, testes, etc. Ou seja, você não precisa mais entrar no site do log4j, baixar um zip com vários jars e ter que procurar quais jars devem ser colocados no classpath! No Repositório de Bibliotecas do Maven você encontra os jars que você pode colocar como dependência do seu projeto, e o pedaço de xml que você deve copiar e colar dentro da tag dependencies do seu pom para incluir essas bibliotecas.
Todos os jars baixados pelo Maven são guardados na pasta repository dentro da M2_HOME que você configurou quando instalou o Maven. Assim, se mais de um projeto seu depende do mesmo jar, ele não é baixado de novo.
A grande diferença entre o build.xml do Ant e o pom.xml do Maven é o paradigma. No Ant usamos esse XML praticamente como uma linguagem de programação, onde você da comandos em relação ao build do projeto. No Maven usamos o XML para definir a estrutura do projeto, e a partir dessas declarações o Maven possui targets bem definidos que usam essas informações para saber como realizar aquela tarefa. Um exemplo: para compilar com o Ant criamos um target que chama o javac, mas para compilar com o Maven usamos um target já existente (não o criamos), e ele vai usar a informação que define onde está o código fonte e para onde ele deve ser compilado (sendo que muitas dessas informações possuem convenções e defaults, e nem precisam ser configuradas).
Além dos principais targets do Maven, você pode executar targets de plugins. Você só precisa digitar na linha de comando:
mvn [nomedoplugin]:[target]
e então o Maven baixa o plugin, se necessário, e executa a target pra você. Existe uma lista bem grande de plugins do Maven e uma boa parte desses plugins podem ser usados sem nenhuma configuração adicional no seu pom.
Para dar um exemplo de plugin do Maven nada melhor do que o plugin que cria um protótipo de projeto do Maven: o Archetype. É bem parecido com o scaffold do Ruby: ele cria um protótipo de projeto a partir de um modelo escolhido. O jeito mais fácil de usar esse plugin é digitando na linha de comando:
mvn archetype:create
E então o Archetype vai perguntar qual é o tipo de projeto que você deseja, o groupID, artifactID, version e o pacote referentes ao seu projeto. Depois disso você terá uma estrutura de projeto pronta para ser usada.
Por exemplo se você escolheu o tipo de projeto maven-archetype-quickstart, o Archetype vai criar uma estrutura de pastas parecidas com a seguinte:
teste
|-- pom.xml
`-- src
|-- main
| `-- java
| `-- br
| `-- com
| `-- caelum
| `-- teste
| `-- App.java
`-- test
`-- java
`-- br
`-- com
`-- caelum
`-- teste
`-- AppTest.java
E então é só continuar o seu projeto a partir daí. O código de teste já vem separado do código principal, e o junit já vem como dependência da aplicação. Você também pode criar as pastas src/main/resources e src/test/resources para colocar os recursos (arquivos de configuração, de teste, e etc) do código principal e do de testes, respectivamente. Tudo que estiver dentro dessas pastas é copiado diretamente para o diretório onde as classes são compiladas, sem que seja necessário fazer nenhuma configuração adicional.
Se você, por algum motivo, não gostou da estrutura que o Maven criou, ou está querendo migrar um projeto para o Maven que não segue essa estrutura, você pode configurar os diretórios do projeto
acrescentando algumas linhas no pom:
<project>
...
<build>
<sourceDirectory>
${project.basedir}/src/java/main
</sourceDirectory>
<testSourceDirectory>
${project.basedir}/src/java/test
</testSourceDirectory>
<resources>
<resource>
<directory>
${project.basedir}/src/resources/main
</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>
${project.basedir}/src/resources/test
</directory>
</testResource>
</testResources>
</build>
...
</project>
Nesse exemplo o diretório principal de código e de recursos estarão em src/java/main e src/resources/main respectivamente, e os diretorios de teste em src/java/test e src/resources/test.
Agora com um projeto Maven já preparado, vamos para a principal funcionalidade: o build. O build do Maven é baseado no conceito de ciclo de vida: o processo de construção e distribuição da sua aplicação é dividido em partes bem definidas chamadas fases, seguindo um ciclo. O ciclo padrão é o seguinte:
- compile – compila o código fonte do projeto
- test – executa os testes unitários do código compilado, usando uma ferramenta de testes unitários, como o junit.
- package – empacota o código compilado de acordo com o empacotamento escolhido, por exemplo, em JAR.
- integration-test – processa e faz o deploy do pacote em um ambiente onde os testes de integração podem ser rodados.
- install – instala o pacote no repositório local, para ser usado como dependência de outros projetos locais
- deploy – feito em ambiente de integração ou de release, copia o pacote final para um repositório remoto para ser compartilhado entre desenvolvedores e projetos
Você pode invocar qualquer dessas fases na linha de comando, digitando:
mvn [fase]
Por exemplo se você digitar mvn package o Maven vai executar todas as fases anteriores do ciclo até a fase package. Uma lista completa das fases do ciclo de vida possíveis pode ser encontrada aqui.
Algumas das fases do ciclo possuem plugins associadas a elas, e esses plugins são executados assim que a fase é chamada para ser executada. Você pode também registrar plugins para rodarem em qualquer fase do ciclo, conseguindo, assim, personalizar o build do seu projeto facilmente. Por exemplo, se você quiser criar um jar com o código fonte do projeto, e que esse jar seja gerado depois que o projeto foi empacotado, é só acrescentar no seu pom:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Assim, o plugin Source vai executar seu goal jar na fase package do ciclo de vida. É como se fosse chamado mvn source:jar quando o build passa pela fase de package. A fase package já possui um plugin associado a ela: o jar:jar (supondo que é um projeto jar), então o plugin source só será executado depois do jar:jar. Em geral se você registrar mais de um plugin pra mesma fase, eles serão executados na ordem em que eles forem declarados. O jeito de configurar o plugin para colocá-lo dentro de uma fase do ciclo geralmente está no site principal do plugin, na seção Usage.
O Maven possui ainda outras funcionalidades interessantes, como geração de relatórios. Alguns plugins também merecem uma atenção especial, como o Eclipse que gera informações de projeto para o eclipse (.classpath e .project), o Antrun que te permite executar código Ant dentro do Maven, o Cobertura que gera um relatório mostrando a cobertura de testes no seu projeto, o Jetty que sobe uma instância do Jetty com sua aplicação deployed, o Selenium que sobe uma instância do servidor do Selenium para poder fazer os testes de aceitação do selenium, enfim, existem vários plugins interessantes e é relativamente fácil achar o plugin que faz o que você precisa. É igualmente fácil, também, fazer um plugin para o Maven, o chamado Mojo.
Aqui na Caelum, além do Maven e JUnit, usamos muito o Selenium, juntamente com o SeleniumDSL, para os testes de integração, e o Cruise Control para o controle da integração contínua. Esperamos colocar tutoriais e vídeos sobre essas ferramentas também.
Lucas Cavalcanti
Mais sobre o autor
21 Respostas para “Processo de build com o Maven”
Trackbacks/Pingbacks
-
-
novembro 12, 2010
[...] de ferramentas de build que vêm ganhando espaço ultimamente são o gradle e o buildr, e o maven, todos correndo atrás de suportar o maior número possível de linguagens na [...]
-
-
fevereiro 26, 2012
[...] Livro Maven by Example [2] Processo de build com o Maven [3] Introduction to m2eclipse [4] Introduction to the POM [5]Introduction to the [...]
ASSINE NOSSO RSS
Bruno Andrade
07. jul, 2008
olá lucas,
muito bom o artigo,uma curiosidade como vocês da caelum fazem no dia a dia, quero dizer usam wtp(eclipse)+maven ou maven e eclipse só para codificar mesmo?
Lucas Cavalcanti
07. jul, 2008
Olá Bruno,
a gente costuma usar o eclipse com wtp e maven… Se o seu projeto for web, você pode ainda passar um parametro adicional para que o seu projeto vire um projeto web no eclipse:
mvn eclipse:eclipse -Dwtpversion=2.0
ou mude a versão pra versão do wtp…
Fernando Boaglio
08. jul, 2008
Bom artigo para introdução ao Maven2, com certeza o seu uso é como você disse, ou as pessoas adoram ou detestam.
Sugiro também além do link que você publicou, essa engine de busca: http://maven.ozacc.com/ e o uso do plugin do eclipse: http://m2eclipse.codehaus.org/
Diego Carrion
08. jul, 2008
Muito bom o post.
Dennys
08. jul, 2008
Bacana! Ja uso o maven faz algum tempo… junto com o Continuum…
Vou plugar meu listener aqui para ver quando vai sair algo com o Cruise Control, Selenium… hehehe
Abraços!
mauricio gamarra
08. jul, 2008
Um grande problema que tenho com o maven com eclipse, mesmo usando o m2eclipse é debugar aplicações web, nunca consegui.
Alguém tem alguma dica de como fazer?
Abraços
Lucas Cavalcanti
08. jul, 2008
A versão nova do m2eclipse tem uma integração com o WTP que já transforma o projeto em projeto web. E o plugin eclipse:eclipse do maven tem uma opção pra usar o wtp também.
É só instalar um servidor web no eclipse e fazer o deploy do seu projeto nesse servidor.
Dá pra subir o servidor em modo debug… Isso deve funcionar
Donizetti
10. jul, 2008
Ola Bruno….Otimo post…
So gostaria de perguntar oque é o SeleniumDSL ??? =D
Antonio Kantek
12. jul, 2008
Eu gosto muito do Team City. Acho ele um bom competidor para o Cruise Control.
Bruno
14. jul, 2008
Parabéns pelo post, muitas vezes o pessoal desanima por ter que apagar incêncio e falta de tempo para artigos gigantes sobre o assunto.
Danilo Torres
17. jul, 2008
Olá todos,
Bom, tenho procurado muitos artigos, fóruns sobre o plugin m2eclipse, porém tenho encontrado uma certa dificuldade em encontrar um bom material, visto que a grande maioria informa os comandos que devem ser passados para executar as fazer e tal… (inclusive neste artigo – por sinal bastante simples e eficiente). Gostaria de saber se mesmo com o m2eclipse é necessário estar com o cmd aberto para executar os comandos do maven2
valeu!
Lucas Cavalcanti
17. jul, 2008
Então Danilo, com o plugin m2eclipse é só colocar o projeto como gerenciado pelo plugin e vc provavelmente não vai precisar rodar os targets do maven na mão. Se mesmo assim você precisar rodar algum plugin do maven, é só ir em Run As >> Maven build e colocar o target… Não precisa estar com o cmd aberto…
[]‘s
Luiz
19. jul, 2008
Olá, Lucas!
Pelo que eu sei, o mvn package gera um jar apenas com seu projeto, sem os jars de que ele depende. Existe algum comando para o maven que gere o jar com as dependências inclusas?
Ah! Parabéns pelo post! Muito bom!
Lucas Cavalcanti
20. jul, 2008
Olá, Luiz,
existe o plugin shade que cria um uber-jar com as dependências inclusas… nunca usei, mas deve resolver o problema…
[]‘s
paulo
20. nov, 2008
oi, tenho uma dúvida parecida com a do luiz (coment 13).
Como faço para rodar um jar gerado pelo maven usando o comando java no terminal? quando tento fazer isso, estou usando jdbc com mysql, dá um erro de classe não encontrada. o comando é mais ou menos java -jar myapp.jar. como faço para minha aplicação enxergar as dependências que já foram baixadas para o repositório local.
Lucas Cavalcanti
20. nov, 2008
pra rodar o jar, vc precisa colocar todas as dependencias no classpath:
java -classpath -jar myapp.jar
Fred
30. jan, 2009
Tenho utilizado o maven com um amigo nos projetos da empresa em que trabalhamos e tb tenho utilizado ele em casa nos estudos.
O maven realmente ajuda muito e automatiza muito.
Ontem precisei alterar um jar do tomahawk para uma versão mais nova, então eu somente entrei no pom.xml ou na administração do eclipse e alterei o número da versão…. ele automaticamente retirou o antigo arquivo e baixou a versão desejada.
José
03. mai, 2012
Olá Lucas, antes de mais nada quero lhe dar os parabéns pelo post, muito bom.
Quero te pedir uma ajuda, estou tentando trabalhar com o Maven 3.0.4 e o plugin M2eclipse, mas estou encotrando problemas, fiz as configurações e quando tento criar um projeto no eclipse “Maven Project”, e tento trabalhar com o maven-archetype-webapp da o seguinte erro:
Could not resolve archetype org.apache.maven.archetypes:maven-archetype-webapp:RELEASE from any of the configured repositories.
já fiz de tudo pra tentar resolver, mais não consegui, tem como você me ajudar?
Fabiano Góes
12. set, 2012
Olá Lucas, ressuscitando esse post sobre Maven, primeiro quer dar parabéns pelo excelente post.
Esse “Cruise Control” tem o mesmo papel do Hudson??
O que exatamente é o Selenium?
Outra coisa: usando o plugin maven/eclipse você cria o projeto direto no Eclipse ou cria via cmd e depois importa no eclipse?