Instalando e usando Maven

O que é Maven?

Apache Maven, ou simplesmente Maven, é uma ferramenta para gerenciamento e automação de projetos em Java. Ela é similar à ferramenta Ant, mas possui um modelo de configuração mais simples, baseado no formato XML. Maven é um projeto da Apache Software Foundation.

Maven utiliza uma construção conhecida como Project Object Model (POM). Ela descreve todo o processo de construção de um projeto de software, suas dependências em outros módulos e componentes e a sua sequência de construção. O Maven contém tarefas pré-definidas que realizam funções bem conhecidas como compilação e empacotamento de código. Neste arquivo também encontramos as definições das características do projeto desde as informações básicas tais como nome, desenvolvedores, repositórios de código fonte (versionamento de código fonte, como CVS, Subversion e Git), dependências de bibliotecas externas e até alguns outros plugins que ajudam no desenvolvimento, testes e até implantação do artefato gerado. Uma grande característica do Maven é que ele é construído para trabalhar em rede. O núcleo da ferramenta pode baixar plugins de um repositório. (o mesmo repositório utilizado pelos outros projetos Java do Apache e outras organizações (ex: JBoss). O Maven disponibiliza suporte nativo para a recuperação de arquivos deste repositório, e para a inclusão dos artefatos resultantes no final do processo. Um cache de artefatos atua como ponto de sincronização dos artefatos de um projeto local. Um bom exemplo para o Maven é a possibilidade de instalar um código fonte de exemplo diretamente de um servidor, fazer o download de todas as bibliotecas necessárias, compilar todos os códigos-fonte, testar alguns métodos necessários, aplicar validações de qualidade de código, baixar um servidor web, instalar a aplicação neste servidor, inicia-lo e já estaremos acessando a aplicação de exemplo. Como isto é possível? A resposta é simples: Maven. Logo veremos como fazer isto. Mesmo sabendo sobre os pontos mencionados acima, o Maven ainda tem muito mais a oferecer. Esta ferramenta prega a padronização dos projetos. As configurações dos projetos são semelhantes já que sempre estarão organizados em uma estrutura semelhante. Seguir padrões é algo muito importante e o Maven sabe disso. Visite o link Maven para maiores informações sobre esta ferramenta.

A origem do Maven

O Maven surgiu com o objetivo de simplificar os build files do Ant utilizados nos projetos desenvolvidos pela equipe do projeto Jakarta Turbine. Eles procuravam uma maneira de deixar os seus projetos organizados em uma mesma estrutura padronizada e também não queriam mais perder tempo no envio de bibliotecas para os sistemas de controle de versão. Neste momento surgiu a primeira versão da ferramenta. Em 2005 ela foi completamente reescrita, surgindo o Maven 2, o resultado sobre toda a experiência dos desenvolvedores e usuários da primeira versão. Em Janeiro de 2011 foi liberada a versão 3.x. O Maven também evolui.

Os principais recursos disponíveis no Maven

O Maven é uma ferramenta muito interessante porém as vezes mal compreendida. Abaixo, de forma simplificada os principais recursos disponíveis.

A criação de um projeto é muito simples. Além disso isto é feito seguindo as melhores práticas. Comece o desenvolvimento de um novo projeto em poucos segundos, uso consistente em todos os projetos não significa um tempo de aprendizado muito grande para novos desenvolvedores que estão iniciando em um projeto. Gerenciamento avançado através de atualizações automáticas e resolução de dependências (também conhecidas como dependências transitivas). Habilidade de trabalhar com vários projetos ao mesmo tempo. Grande quantidade de repositórios para as bibliotecas já disponíveis assim como suas atualizações com disponibilidade em tempo real. Grande extensibilidade já que é possível facilmente criar novos plugins em Java ou até mesmo em linguagens de script. Acesso praticamente imediato a novos recursos sem a necessidade de configuração extra. Possibilidade de criar tarefas ant(no próprio build.xml característico do ant) com gerenciamento de dependências sem usar diretamente o Maven (pom.xml).

Modelo baseado em builds: Maven possui a habilidade de criar uma infinidade de projetos com formatos distintos(ear,jar,webstart,war,ejb etc) com distribuição através do conceito de metadados para cada projeto sem a necessidade de criar qualquer script para a maioria dos projetos.

Criação de site com informações importantes sobre o projeto. Usando também o mesmo conceito de metadados para construção de um projeto, o Maven pode gerar um site ou um PDF com a inclusão de toda a documentação que for configurada como necessária. Um bom exemplo para isto é a necessidade de criação de relatórios sobre o estado de desenvolvimento do projeto.

Controle e Gerenciamento das distribuições de novos artefatos sem a necessidade de inúmeras configurações. O Maven se integra com o controle de versionamento do seu projeto (CVS, SVN, Git, etc), gerenciando e liberando novas versões do artefato para um local ou locais específicos para compartilhamento com outros projetos. Maven é capaz de publicar arquivos individuais, tais como um jar, um arquivo e suas respectivas dependências, documentação e até um pacote com distribuição do código fonte.

Gerenciamento de Dependência: Maven incentiva o uso de um repositório central de arquivos JARs assim como suas dependências. Existe um mecanismo que permite que os clientes do seu projetos possam simplesmente fazer o download dos arquivos necessários para a construção dos seus projetos. Para isto basta apenas distribuir a sua biblioteca em um repositório central. A grande vantagem é que isto permite que os usuários do Maven distribuam os seus projetos JARs e incentiva a comunicação entre os projetos para garantir que as questões de compatibilidade com versões anteriores sejam abordadas.

O que o Maven faz que não posso fazer no Ant?

Esta é uma pergunta de muitos, os que não conhecem o Maven por Exemplo, quem sabe talvez os conservadores também?

O Maven não faz nada além do que você mesmo possa fazer através do Ant. A diferença é que o Maven fica responsável por tarefas que você tem que criar através do Ant. Na prática por exemplo, sabemos que para criar testes unitários via Ant é necessário um certo esforço. No Maven isto já está nativamente disponível em seu projeto apenas executando o comando mvn test. Ele automaticamente compila o código necessário e cria o ambiente de testes unitário conforme as classes de Testes previamente definidas e finalmente testa as classes. Simples não? Imagine fazer isto na mão?

O maven também possui centenas (por que não milhares?) de plugins ou wizards prontos para o seu uso. A quantidade de plugins do maven é superior (e muito) a quantidade de Ant Tasks disponíveis. No Ant por exemplo, se é criada uma nova Ant Task e você quer usá-la é necessário fazer o download dos pacotes necessários e configurar no build.xml. Esta prática no Maven pode ser automática, sem a necessidade de ficar verificando uma nova versão, downloads e configurações. Isto é automático.

Ciclo de vida de construção de um projeto Maven

Maven é baseado no conceito de ciclo de vida de projeto. Isto significa dizer que o processo para construção de um determinado artefato é claramente definido.

Para a construção de um projeto específico é necessário aprender uma lista de comandos e o Maven, através das definições do POM, será responsável por gerar os artefatos conforme desejado.

Existem 3 tipos de ciclo de vida de construção do projeto: default, clean e site. O default trabalha com o a construção dos artefatos desde a criação até a instalação. O clean é responsável pela limpeza de todos os arquivos gerados no ciclo default. O ciclo site é responsável pela criação da documentação do projeto.

O Ciclo de Vida de um projeto é dividido em fases

Cada um dos ciclos acima explicados são definidos por um grupo diferente de fases, onde cada fase representa um estágio no ciclo de vida do projeto. Por exemplo, o ciclo default possui as seguintes fases:

  • validate – valida se o projeto está correto e se todas as informações necessárias estão disponíveis
  • compile – compila o código fonte do projeto
  • test – testa o código compilado usando uma framework de testes. Estes testes não necessitam do código fonte.
  • package – reúne o código compilado e empacota em algum formato especificado, por exemplo, um jar ou um war.
  • integration-test – processa e instala o pacote caso seja necessário em um ambiente onde os testes serão executados.
  • verify – executa algumas verificações para identificar se o pacote é válido e se atende os critérios de qualidade
  • install – instala o pacote em um repositório local, para ser usado como uma dependência em outros projetos locais.
  • deploy – realizado em um ambiente de integração ou distribuição, copia o pacote para um repositório remoto para compartilhamento com outros desenvolvedores ou projetos.

Estas fases de construção (levando em consideração que existem outras fases ainda não mencionadas) são executadas de forma sequencial até completar todo o ciclo de vida default. Isto significa que o Maven irá primeiro validar o projeto, após irá compilar os códigos-fonte, executar os testes, empacotar os arquivos binários (caso seja um jar), executar os testes de integração, verificar o pacote, instalar o pacote verificado para o repositório local e distribuir o pacote instalado em um ambiente específico.

Para executar todos os passos acima é necessário apenas solicitar a execução da última fase especificada, ou seja, deploy: mvn deploy.

Caso execute o comando mvn install as seguintes fases serão executadas, validate, compile, package etc.

Também existem casos onde é necessário executar mais de um comando para vários módulos (um bom exemplo é um projeto com sub-projetos). Por exemplo, podemos executar mvn clean install. Este comando irá verificar todos os sub-projetos e executar os comandos clean e depois install (incluindo todos os passos necessários).

Uma fase de construção é composta de metas

Embora que uma fase de construção seja responsável por um passo específico no ciclo de vida do projeto, a maneira a qual trata suas responsabilidades podem variar. Esta execução é feita através da declaração de metas para cada fase.

Uma meta (goal) representa uma tarefa específica (entre várias tarefas existentes na fase) a qual contribui para a construção e gerenciamento do projeto. Estas fases podem estar ligadas a nenhuma ou muitas fases de construção. Uma tarefa que não está associada a nenhuma fase pode ser executada fora do ciclo de vida apenas por sua invocação direta. A ordem de execução depende da ordem a qual a tarefa(s) e as fase(s) de construção serão invocadas. Por exemplo, considere o exemplo abaixo. Os argumentos clean e package são fases de construção enquanto dependency:copy-dependencies é uma meta (ou tarefa).

mvn clean dependency:copy-dependencies package

Caso este comando for executado, a fase clean será executada primeiro (executando todas as tarefas precedentes ao ciclo clean do projeto até a própria fase clean), e depois, a meta dependency:copy-dependencies e, finalmente, executando a fase package (representando todas as fases precedentes ao ciclo default do projeto). Além disso, se uma meta está associada a nenhuma ou várias fases, a meta será invocada em todas as fases. A fase de construção pode ter nenhuma ou algumas metas para completá-la. Caso uma fase não possua tarefas para ser executada a fase não será executada. Caso existam uma ou mais tarefas a serem completadas, todas as tarefas serão executadas.

Os principais recursos disponíveis no Maven

O Maven é uma ferramenta muito interessante porém as vezes mal compreendida. Abaixo, de forma simplificada os principais recursos disponíveis. A criação de um projeto é muito simples. Além disso isto é feito seguindo as melhores práticas. Comece o desenvolvimento de um novo projeto em poucos segundos.

  • O uso consistente em todos os projetos não significa um tempo de aprendizado muito grande para novos desenvolvedores que estão iniciando em um projeto.
  • Gerenciamento avançado através de atualizações automáticas e resolução de dependências (também conhecidas como dependências transitivas).
  • Habilidade de trabalhar com vários projetos ao mesmo tempo.
  • Grande quantidade de repositórios para as bibliotecas já disponíveis assim como suas atualizações com disponibilidade em tempo real.
  • Grande extensibilidade já que é possível facilmente criar novos plugins em Java ou até mesmo em linguagens de script.
  • Acesso praticamente imediato a novos recursos sem a necessidade de configuração extra.
  • Possibilidade de criar tarefas ant (no próprio build.xml característico do ant) com gerenciamento de dependências sem usar diretamente o Maven (pom.xml).
  • Modelo baseado em builds: Maven possui a habilidade de criar uma infinidade de projetos com formatos distintos (ear, jar, webstart, war, ejb, etc) com distribuição através do conceito de metadados para cada projeto sem a necessidade de criar qualquer script para a maioria dos projetos.
  • Criação de site com informações importantes sobre o projeto. Usando também o mesmo conceito de metadados para construção de um projeto, o Maven pode gerar um site ou um PDF com a inclusão de toda a documentação que for configurada como necessária. Um bom exemplo para isto é a necessidade de criação de relatórios sobre o estado de desenvolvimento do projeto.
  • Controle e Gerenciamento das distribuições de novos artefatos sem a necessidade de inúmeras configurações. O Maven se integra com o controle de versionamento do seu projeto (CVS, SVN, ClearCase, etc), gerenciando e liberando novas versões do artefato para um local ou locais específicos para compartilhamento com outros projetos. Maven é capaz de publicar arquivos individuais, tais como um jar, um arquivo e suas respectivas dependências, documentação e até um pacote com distribuição do código fonte.
  • Gerenciamento de Dependência: Maven incentiva o uso de um repositório central de arquivos JARs assim como suas dependências. Existe um mecanismo que permite que os clientes do seu projetos possam simplesmente fazer o download dos arquivos necessários para a construção dos seus projetos. Para isto basta apenas distribuir a sua biblioteca em um repositório central. A grande vantagem é que isto permite que os usuários do Maven distribuam os seus projetos JARs e incentiva a comunicação entre os projetos para garantir que as questões de compatibilidade com versões anteriores sejam abordadas.

Instalando o Maven na sua máquina

Para instalar o Maven é necessário visitar a página oficial de download do projeto: download aqui

Sugiro que instale a versão atual disponível. Descompacte o conteúdo em um diretório de sua escolha no seu computador e adicione a pasta “/bin” do diretório onde o conteúdo do arquivo está descompactado no PATH do sistema operacional.

Como exemplo, estou usando o Windows 7 e segui os seguintes passos: Painel de Controle>Sistema e Segurança>Sistema:

Painel de Controle

E depois cliquei no link Configurações avançadas do sistema, no botão Variáveis de Ambiente e adicionei a seguinte linha no final da variável de sistema PATH: K:\programas\apache-maven-3.0.4\bin

Variável de Ambiente

Também é necessário que a variável de ambiente “JAVA_HOME” esteja definida com o diretório de instalação do JDK. Após os passos acima abra a linha de comando do seu sistema operacional e digite “mvn –v” para visualizar a versão do maven. Segue o resultado da execução, caso o resultado seja muito diferente, por favor verifique se tudo está configurado conforme esperado.

Shell Command

Guia de propriedades existentes no Maven

O maven possui uma lista de propriedades que são muito úteis na criação de um novo projeto. No Maven 3 todas as propriedades pom.* foram descontinuadas. Agora as propriedades iniciam com project.*.

Propriedades de Build

# representa o diretório que contem o pom.xml
${basedir}
# é equivalente a ${project.version} ou ao antigo 
${version}
${pom.version}

Propriedades POM/PROJECT

Todos os elementos contidos no pom.xml podem ser referenciados com o prefixo project ou através do prefixo pom.

<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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>ziben</groupId>
	<artifactId>ziben-model</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>ziben-model</name>
	<description>ziben-model</description>
	<build>
		<sourceDirectory>src</sourceDirectory>
		<resources>
			<resource>
				<directory>src</directory>
				<excludes>
					<exclude>**/*.java</exclude>
				</excludes>
			</resource>
		</resources>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-clean-plugin</artifactId>
				<version>2.4.1</version>
				<executions>
					<execution>
						<!-- Aqui estou forçando um clean toda vez que o maven install for executado. -->
						<id>auto-clean</id>
						<phase>initialize</phase>
						<goals>
							<goal>clean</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
		<pluginManagement>
			<plugins>
				<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself. -->
				<plugin>
					<groupId>org.eclipse.m2e</groupId>
					<artifactId>lifecycle-mapping</artifactId>
					<version>1.0.0</version>
					<configuration>
						<lifecycleMappingMetadata>
							<pluginExecutions>
								<pluginExecution>
									<pluginExecutionFilter>
										<groupId>org.apache.maven.plugins</groupId>
										<artifactId>maven-clean-plugin</artifactId>
										<versionRange>[2.4.1,)</versionRange>
										<goals>
											<goal>clean</goal>
										</goals>
									</pluginExecutionFilter>
									<action>
										<ignore></ignore>
									</action>
								</pluginExecution>
							</pluginExecutions>
						</lifecycleMappingMetadata>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>
	<dependencies>
	    <dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
			<scope>provided</scope>
	    </dependency>
	    <dependency>
	    	<groupId>postgresql</groupId>
	    	<artifactId>postgresql</artifactId>
	    	<version>9.1-901.jdbc4</version>
	    </dependency>
	    <dependency>
		  	<groupId>commons-logging</groupId>
		 	<artifactId>commons-logging</artifactId>
		  	<version>1.1.1</version>
		  	<scope>provided</scope>
    	</dependency>
	</dependencies>
</project>

Configurações Locais

Propriedades definidas no arquivo settings.xml local na pasta do usuário podem ser referenciadas diretamente em seu projeto através do prefixo settings.

# é uma referência ao repositório local definido no settings.xml
${settings.localRepository}

Aos que ainda não conhecem este arquivo sugiro consultar a pasta: C:\Documents and Settings\<seu_usuario_windows>\.m2\settings.xml ou no caso do Linux em ~/.m2/settings.xml.

Variáveis de Ambiente

As variáveis de ambiente podem ser referenciadas apenas usando o prefixo env…

# informa o diretório raiz onde está instalada a versão do Maven.
${env.M2_HOME}
#  indica o diretório da instalação do JRE_HOME. Para usar corretamente em seu projeto sugiro usar conforme o exemplo abaixo
${java.home}
<properties>
  <jvm>${java.home}../bin/java.exe</jvm>
</properties>

Propriedades Customizadas no Projeto

No Maven existe a possibilidade de criar novas propriedades em seu projeto (conforme visto inclusive no exemplo de variáveis de ambiente acima).

Veja um exemplo:

<project>
...
  <properties>
     <nome.ambiente>desenvolvimento</nome.ambiente>
     <versao.biblioteca>1.2.3</versao.biblioteca>
  </properties>
...
</project>

Para usar estas variáveis em seu projeto basta apenas inserir o código ${nome.ambiente} e ${versao.biblioteca}.

Propriedades herdadas de um Projeto Pai

Para usar propriedades definidas em um projeto Pai basta apenas usar o prefixo ${project.parent}.

Uma boa forma de determinar quais são as possíveis variáveis que podem ser acessadas de um projeto pai é pesquisar a API do Maven. Nesta postagem usei a versão do Maven 3.0.4. Está acessível em http://maven.apache.org/ref/3.0.4. (Sempre verifique a obsolescência das versões!)

Qual é a estrutura padrão de diretórios e arquivos no Maven?

O uso de diretórios pré-configurados pelo Maven permite que novos usuários se familiarizem imediatamente com um novo projeto Maven. Podemos dizer que é análogo a uma mudança aparência de um site onde conhecemos a sua estrutura e sabemos como usá-lo, mesmo após mudando apenas o modelo (template).

Irei informar os diretórios e em quais contextos os mesmos se aplicam dentro da estrutura do projeto.

src/main/java – Diretório onde está o código fonte Java da Aplicação e/ou Biblioteca

src/main/resources – Arquivos de configuração e outros arquivos devem ficar nesta pasta

src/main/filters – Pasta onde contém arquivos que podem ser configurados conforme o ambiente e/ou profile usado

src/main/assembly – Pasta que possui arquivos descritores de configuração da construção de um determinado artefato

src/main/config – Arquivos de configuração

src/main/webapp – Pasta para conteúdo Web. Aqui se encontra todos os arquivos fonte da parte web.

src/test/java – Pasta que contém os arquivos de testes unitários

src/test/resources – Pasta com arquivos que serão utilizados pelas classes de testes unitários

src/test/filters – Análogo ao diretório src/main/filters só que usado apenas para testes.

src/site – Diretório onde está a configuração do site de documentação do projeto.

LICENSE.txt – Arquivo de licença do projeto

NOTICE.txt – Avisos e atribuições necessárias para uso de bibliotecas as quais o projeto depende.

README.txt – Arquivo Leia-me do projeto.

Muito comum é usar também a estrutura do Eclipse,  usando somente ./src, e WebContent no lugar de webapp.

Na pasta raiz do projeto inicialmente existe apenas o pom.xml assim como arquivos secundários tais como propriedades, build.xml (caso esteja também usando o Ant) e os diretórios src e target (este último será gerado apenas após a execução de alguns comandos tais como mvn compile, mvn package, mvn install etc).

Conforme descrito o src é onde está todo o código fonte necessário para o projeto. A pasta target é o local onde todos os artefatos necessários para a criação dos pacotes do projeto serão gerados. Nunca versione esta pasta (CVS, SVN, Git, etc). Ela pode ser apagada (ignore) sem problemas e o Maven também pode fazer isto (mvn clean).

Usamos como base um projeto com códigos fonte Java, porém podem existir outras pastas de arquivo fonte tais como Antlr (src/main/antlr) e Groovy (src/main/groovy); não será nosso caso.

Sugiro que use as configurações conforme especificado acima e será possível, como exemplo, criar a seguinte estrutura de projeto para um projeto war (vamos dizer que seu projeto esteja na pasta C:\_desenv\ws-myproject):

Uma estrutura muito comum, derivada do “padrão” Eclipse

Bom, e se temos um legado?… adaptações são perfeitamente suportadas e validadas pelo Maven, portanto nada de anormal. A estrutura fica um pouco modificada, mas bastam configurações no settings.xml do usuário e tudo se resolve. Mas não se preocupe, pois o maven pode trabalhar sem ele, e nesse caso usará o repo do Maven, sendo necessário acesso à Internet.

Como configurar o Maven no Eclipse

A melhor forma para usar o Maven dentro da IDE Eclipse é através do plugin m2eclipse.

Este plugin do Eclipse facilita o gerenciamento simultâneo de projetos simples e compostos (projetos com vários módulos), permitindo a build através da interface da própria IDE, interagindo com os repositórios Maven fazendo o desenvolvimento ainda mais fácil através da integração entre os projetos. Através do m2eclipse você pode usar o Maven com Eclipse naturalmente através de uma interface intuitiva.

Para instalar é necessário configurá-lo através do update-site abaixo:

m2eclipse Core Update Site: http://download.eclipse.org/technology/m2e/releases

Para maiores informações visite o site do plugin.

Após instalar o plugin do Maven para Eclipse (tem que sair mesmo e reiniciar o Eclipse!), você precisa instalar um “extra”, mas dessa vez vamos usar o Market Place do Maven: no menu Window->Preferences, depois Maven->Discovery, pressione “Open Catalog”.

Open Catalog - maven

Depois check o item “buildhelper”; acredite, você vai precisar!

Buildhelper

Bom, basta ir em frente e não esqueça de reiniciar o Eclipse depois!

Suerte!