segunda-feira, 9 de junho de 2014

Curso Maven Pro: Lição 1 - "Odeio Maven!"



Bem vindo(a) ao nosso curso de Maven "Maven Pro". Aqui, você vai aprender gratuitamente como usar o Maven para criar, compilar, testar e distribuir seus projetos Java, de forma simples e prática. Esta é a primeira lição do curso (total de 3), e é composta por: Demonstração (vídeo), Texto e Exercício.





Lição 1: “Odeio Maven”

Antes de começar, assista ao vídeo demonstrativo da lição!
  • Visão geral sobre o Maven, como usá-lo adequadamente;
  • Demonstração de criação e compilação de um projeto simples;
  • Análise de um "pom.xml" básico;
  • Dependências e repositórios;
  • Maven no eclipse;
  • Processo de transformação de um projeto normal em Maven;
  • Exercício.

O que é o Maven?

  • Uma ferramenta para criar e compilar projetos Java;
  • Uma ferramenta para gerir dependências em projetos Java;
O Apache Maven (http://maven.apache.org/) pode ser definido por essas duas afirmativas. É exatamente o que ele é e para que ele serve.
Antes do Maven, nós usávamos coisas como “GNU Make”, ou no caso do Java, “Apache Ant” para configurar e compilar projetos.
É claro que você pode usar a própria IDE para isso, porém, isso diminui a sua portabilidade, em outras palavras, TODOS os desenvolvedores devem utilizar a mesma IDE, com os mesmos plugins, na mesma versão.
Além disso, a obrigatoriedade de uso de uma IDE impede a compilação automatizada, que ocorre em Servidores de Integração Contínua.
Um projeto “Maven” é uma pasta, que contém um arquivo “pom.xml” e um diretório de código-fonte (“src”). Esse arquivo gerencia todas as dependências do Projeto e permite construí-lo, empacotá-lo, analisá-lo e entregá-lo automaticamente.
Eis um exemplo de “pom.xml”:


<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-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.exemplo.projetoteste</groupId>
  <artifactId>projetoteste</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>projetoteste</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

A princípio, o Maven parece complicado, com todas as suas fases, plugins, repositórios e dependências, porém, com o tempo, você se acostuma com ele.

  
5 Razões para usar um gestor de build:
  1. Tornar o projeto independente da IDE;
  2. Tornar o projeto "portátil";
  3. Gerenciar as dependências;
  4. Ter uma interface única para construir o projeto;
  5. Permitir a compilação através de ferramentas automáticas (Continuum, Hudson, Cruise Control, JBE etc);
Existem vários tipos de projeto Java diferentes, cada um com suas características, dependências, ambiente e empacotamento próprios. Além disso, cada um utiliza versões diferentes de componentes, que são as dependências, cujas classes devem estar nos “classpaths” de: Compilação, Teste e Execução.


Se você utiliza uma IDE, tudo isso fica meio “transparente”. É só escolher o tipo de projeto que quer criar e os plugins da IDE fazem o resto. Porém, isso, como já vimos, torna seu projeto dependente da própria IDE. O Maven abstrai isso tudo através das características:
  • Uso de arquétipos de projeto;
  • Gestão de dependências e versionamento;
  • Ciclo de vida de “build” padronizado.


Arquétipos

Sempre que você vai criar um projeto, tem que gerenciar as dependências. Em outras palavras, tem que colocar no “classpath” todas as bibliotecas necessárias para compilar e rodar seu projeto, certo? Além disso, pode ter que fazer algumas configurações, por exemplo: Versão do Java, codificação de caracteres do código-fonte, configurações do Container (se for um projeto Java EE) etc.
Um arquétipo Maven já faz isso para você. Existem arquétipos prontos para vários tipos de projeto, e eles são utilizados para criar projetos, criando o “pom.xml”, com as dependências básicas, e toda a estrutura de pastas necessárias.

Gestão de dependências e versionamento

No Maven não existe esse papo de criar uma pasta “lib” e colocar “jars” dentro dela. Isso se chama “engravidar” o projeto, e é uma prática ruim, pois:
  1. Você tem que armazenar os “jars” junto com o código-fonte do projeto, no repositório SCM (Git, SVN, CVS etc);
  2. Você não sabe se as versões dos “jars” estão adequadas;
  3. Pode gerar conflito no Classpath, caso o Container também possua as mesmas dependências;
Para o Maven, cada “Projeto” é um “Artefato”, que pode ser compilado, empacotado e armazenado em um repositório de artefatos. Um “Projeto” gera um arquivo “war” / “ear” / “jar”, que é identificado pelas “Coordenadas Maven”: GroupId, ArtifactId e Version.
Cada Projeto Maven pode ter dependências, necessárias para compilá-lo e executá-lo. Essas dependências devem estar presentes no “classpath”. E essas dependências, por sua vez, também são Projetos Maven, ou “Artefatos”, que possuem “Coordenadas Maven”.
As dependências ficam armazenadas em um repositório de Artefatos Maven, e seu projeto as copia (ou aponta para elas) em seu “classpath” no momento da compilação ou execução.
E, como essas “Coordenadas Maven” incluem a versão (“version”), você não corre o risco de usar dependências de versões incorretas.

Ciclo de vida de “build” padronizado

O Maven impõe alguns padrões. Isso não é ruim, pois nos ajuda a organizar nosso projeto de tal forma que ele se torna realmente portátil. Você pode não conhecer o projeto, mas saberá como compilá-lo e testá-lo.
Entre esses padrões, está o Ciclo de Vida de “Build” (ou “Construção), que inclui fases distintas, por exemplo:
  • validate – valida o projeto sem compilar;
  • compile – compila o código-fonte;
  • test – executa os testes do projeto;
  • package – empacota o executável para distribuição (JAR);
  • integration-test – testes de integração;
  • verify – executa verificações sobre o código-gerado;
  • install – instala o pacote no repositório maven;
  • deploy – instala o pacote no repositório corporativo.
E existem fases avulsas, como a “clean”, que limpa a pasta binária “target”, onde o Maven coloca o resultado de tudo o que ele faz.
As fases formam uma sequência e, quando os resultados de uma fase anterior não existem, serão gerados. Por exemplo, se rodarmos o comando “mvn clean package”, o maven vai:
  1. Limpar o conteúdo da pasta “<projeto>/target”;
  2. Executar a fase “validate”;
  3. Executar a fase “compile”;
  4. Executar a fase “test-compile”, para compilar os códigos de teste (pasta “src/test/java”);
  5. Executar a fase “test”;
  6. Executar a fase “package”;

Lições importantes sobre o maven

  • O maven impõe uma estrutura para organizar o projeto;
  • O maven impõe coordenadas próprias;
  • O maven impõe uma interface de comandos própria;
  • O maven muda a nossa maneira de trabalhar.


Não insista em desobedecer ao Maven. Se você não concorda com os padrões que ele impõe, então evite usá-lo. Os principais problemas são causados por atitudes como:
  • Continuar “enfiando” “jars” dentro do projeto (dependências com escopo “system”);
  • Deixar de atualizar a versão do projeto;
  • Usar versão “internal” ao invés de “-SNAPSHOT”, mesmo durante o desenvolvimento;
  • Usar apenas repositórios locais ao invés de centrais;

Conceitos fundamentais


Um projeto Maven

Um projeto Maven gera um Artefato Maven, que é empacotado como “ear”, “war” ou “jar”, dependendo do tipo de empacotamento do projeto.
Um projeto Maven é uma pasta com um arquivo “pom.xml” e uma subpasta com o código-fonte (“src”). Não tem arquivos ocultos, como “.settings”, “.project” ou “.classpath”.
Um projeto Maven pode ser criado com base em um Arquétipo, que já traz um modelo de projeto, com dependências e configurações.
Um projeto Maven pode possuir dependências de outros Artefatos Maven, que são identificados por suas “Coordenadas Maven”.

Coordenadas Maven

Todo projeto Maven gera um Artefato Maven, que é identificado por 3 coordenadas:
  • groupId: Identificação da empresa e do sistema aplicativo ao qual o Artefato pertence;
  • artifactId: Identificação deste artefato em particular. Deve ser único dentro do mesmo GroupId;
  • version: Versão do artefato.

groupId

O maven usa um repositório centralizado, e todos os componentes são acessados a partir dele. Logo, é preciso evitar conflitos de nomenclaturas. O “groupId” é como um “namespace” do C++. A convenção é usar:
  1. Nome de domínio da Empresa criadora ao contrário: “com.obomprogramador”;
  2. Nome do grande sistema aplicativo, ao qual o projeto pertence: “metricas”;
Nem todos seguem o mesmo padrão, e, frequentemente vemos “groupIds” estranhos. Evite isso.

artifactId

Cada Projeto Maven gera um único artefato. Logo, seu nome deve identificá-lo univocamente dentro daquele mesmo “groupId”. Não podemos ter dois projetos Maven como mesmo “artifactId” dentro do mesmo “groupId”. Um exemplo seria:
  • groupId: “com.obomprogramador.metricas”
  • artifactId: “validador”;

version

Esta é a coordenada mais polêmica, pois os desenvolvedores, em geral, não sabem versionar seus projetos. Esta coordenada é a versão atual do Projeto Maven e do Artefato que ele gera.
Podem coexistir várias versões do mesmo artefato.
A praxe de controle de versão é: “MM.mm.rr”, onde:
  • “MM” - Major version: Versão principal do software. Assume-se que existam diferenças funcionais significativas entre artefatos cujas versões principais sejam diferentes. Por exemplo: de 1.x.x para 2.x.x;
  • “mm” - Minor vesion: Versão segundária do software. Existem aprimoramentos, porém, existe compatibilidade. Pode ser também um “milestone” de correção de vários “bugs”;
  • “rr” - Revision: Geralmente usado para “bug fix”, sem diferenças significativas.
As versões podem variar conforme o estado do Artefato:
  • internal”: O Artefato está liberado para uso, ou seja, considerado como finalizado. Podemos ter várias versões do mesmo artefato, todas finalizadas. Exemplo: 1.1.5, 1.1.6;
  • snapshot”: O Artefato (ou aquela versão específica) está em desenvolvimento, logo, está em evolução. Isso significa que aquele “pacote” do Artefato é uma visão temporária, que pode ter mudado. Indicamos que a versão é de desenvolvimento ao acrescentar o sufixo: “-SNAPSHOT”. Por exemplo, considere dois pacotes do mesmo artefato, com as versões:
    • “1.1.3”: Versão “internal”, ou seja, liberada para uso;
    • “1.1.4-SNAPSHOT”: Versão “snapshot”, ou seja, a versão 1.1.4 ainda está em desenvolvimento, e esta é uma “foto” de uma de suas compilações;
Alguns desenvolvedores acrescentam outros sufixos à versão “internal”, de modo a marcar “milestones”, por exemplo:
  • “1.1.4-rc1”: É uma versão liberada, mas corresponde ao primeiro “Release Candidate”, ou seja, uma versão considerada aprovada para liberação geral;
  • “1.1.4-final”: É a versão final liberada da versão 1.1.4 do artefato.

Dependências

Uma dependência é um Artefato Maven (criado por um Projeto Maven) que deve estar no “classpath” de um projeto.
As dependências ficam armazenadas em um repositório de artefatos Maven.
No momento da compilação, o Maven busca as dependências do repositório e as coloca no “classpath”.

Já tá ficando “um saco”, não? Um monte de blá-blá-blá sem nenhuma prática, caraca! Então vambora fazer alguma coisa!

Instale a parada toda!


Para o Maven funcionar é necessário que você tenha:
  • O Java JDK instalado. Atenção: Não serve o JRE!
  • O Maven instalado;

Instalando o Java JDK

Para esse curso, vamos usar o JDK 7. Se você quiser usar o JDK 6 ou 5, sem problemas, só se lebre de configurar a versão do Java adequadamente. Nós sempre vamos usar versão “1.6”.
Antes de sair instalando, cara, verifique se você já tem o “javac” instalado. Abra um “terminal”, ou “command prompt” e digite: “javac -version”. Se não der erro, então tá na boa.

Ubuntu:
  • sudo apt-get install openjdk-7-jdk
Fedora, Red Hat:
  • su -c "yum install java-1.7.0-openjdk-devel"
Mac OSX:
Windows:


É de praxe criar a variável de ambiente “JAVA_HOME”:
  • Linux:
    • Altere “/etc/profile” e adicione: “export JAVA_HOME=<pasta onde instalou o Java>. Normalmente é /usr/lib/jvm/openjdk...
    • Altere “/etc/bash.bashrc” e adicione a mesma coisa;
  • Mac OSX:
    • Adicione “JAVA_HOME” dentro de ~/.MacOSX/environment.plist;
    • Altere “/etc/profile” e adicione: “export JAVA_HOME=<pasta onde instalou o Java>.;
  • Windows:
    • Abra “Computador”, propriedades, escolha “Configurações avançadas do sistema”, e clique em “Variáveis de ambiente”. Crie a variável dentro da lista “Variáveis do sistema”.

Instalando o Maven

Neste curso vamos usar o Maven 3.x, na última versão disponível. Em nosso caso, é a versão 3.2.1 (http://maven.apache.org/download.cgi).
Porém, você pode usar qualquer versão do Maven 3, por exemplo, a 3.1.1.


Linux:
  • apt-get update
  • apt-get install ant maven3
Mac OSX:
  • brew install maven (se você instalou o homebrew)
  • sudo port install maven3 (se você usar o mac ports)
Windows:
  • Baixe o maven e o extraia em algima pasta (http://maven.apache.org/download.cgi)
  • Coloque a subpasta “bin” na variável de ambiente “path” (veja o procedimento descrito anteriormente para “JAVA_HOME”);

Crie duas variáveis de ambiente: M2_HOME e M3_HOME, apontando para a pasta onde instalou o Maven. O Maven 3 tinha um “bug” que fazia com que ele usasse a variável “M2_HOME” para apontar para a instalação dele. Só que isso impedia a instalação de Maven 2 e Maven 3 na mesma máquina. Por via das dúvidas, crie as duas.
A documentação do Maven, que é PÉSSIMA, diz que a variável “M2_HOME” (e “M3_HOME”) deve apontar para a pasta onde você descompactou o Maven. Só que os pacotes Linux copiam os arquivos para diretórios diferentes e, as vezes, separam os arquivos. Isso dificulta muito a configuração.
Há um entendimento que deveria ser a pasta onde o executável do Maven (“mvn”) está instalado.


Após instalar o Maven, abra um “terminal” ou “prompt de comandos” e digite: “mvn –version”, para testar. Verifique se a versão exibida é a 3.2.1 (ou a última).

Agora sim!


Tudo instalado e pronto, certo? Então vamos criar um projeto Maven e compilá-lo. Para começar, vamos usar um Arquétipo padrão, chamado: “maven-quickstart-archetype”, que já vem instalado no Maven.
Vamos começar usando um “terminal” (ou “prompt de comandos”), depois eu vou mostrar como fazer isso no Eclipse.
Crie uma pasta para trabalhar, copie e cole o comando abaixo:


Linux / Mac:
mvn archetype:generate \
-DgroupId=com.exemplo.projetoteste \
-DartifactId=projetoteste \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false


Windows:
mvn archetype:generate ^
-DgroupId=com.exemplo.projetoteste ^
-DartifactId=projetoteste ^
-DarchetypeArtifactId=maven-archetype-quickstart ^
-DinteractiveMode=false


A única diferença é que o caractere de continuação de linha. Como o comando é muito grande, é melhor quebrar em várias linhas.

Vai... Tecla <ENTER>, numa boa!


Você criou um projeto Maven! Parabéns! Vamos rever o comando que nós rodamos?
  • “mvn archetype:generate” : Estamos rodando o Maven (comando “mvn”) e pedindo a ele para executar o “goal” “generate” (uma função) de um plugin (uma biblioteca), chamado “archetype”. Este plugin lida com arquétipos e o “goal” “generate” gera um projeto com base em um arquétipo;
  • “-DgroupId=com.exemplo.projetoteste” e “-DartifactId=projetoteste”: Estamos passando duas propriedades (system properties) para a JVM, indicando o “groupId” do nosso projeto e o seu “artifactId”. Poderíamos ter passado a “version” também, mas vamos deixar que ele assuma um valor “default”;
  • “-DarchetypeArtifactId=maven-archetype-quickstart”: Estamos indicando qual é o “artifactId” do arquétipo que queremos usar. Poderíamos ter informado o “archetypeGroupId” também, mas, como esse é um arquétipo default, isso não é necessário;
  • “-DinteractiveMode=false”: Para não encher o saco com perguntas.

Mas... O que eu criei?

Você especificou o “-DartifactId=projetoteste”, certo? Então, dentro da pasta onde rodou o comando, deve haver uma pasta com esse nome.
Lembre-se que um projeto Maven é uma pasta com um arquivo “pom.xml” e uma subpasta “src” contendo o código-fonte.
Se abrirmos esta pasta, veremos a seguinte estrutura:


projetoteste
|
+-"pom.xml"
|
+-src
  |
  +-main
  | |
  | +-java
  |   |
  |   +-com
  |     |
  |     +-exemplo
  |       |
  |       +-projetoteste
  |         |
  |         +-App.java
  | 
  +-test
    |
    +-java
      |
      +-com
        |
        +-exemplo
          |
          +-projetoteste
            |
            +-AppTest.java    

A pasta “src” é dividida entre “main” e “test”, ambas com estrutura parecida. O código-fonte funcional da aplicação fica na estrutura “main” e o código de teste na estrutura “test”. Note que ele criou o caminho do pacote usando o “groupId” que informamos no comando, e, inclusive, criou duas classes: uma funcional (“App.java”) e uma de teste (“AppTest.java”).


Abra o arquivo “pom.xml” e veja seu conteúdo:


<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-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.exemplo.projetoteste</groupId>
  <artifactId>projetoteste</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>projetoteste</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Como podemos ver, as “Coordenadas Maven” do nosso Projeto estão definidas no “pom.xml” (“groupId” e “artifactId”), e ele gerou uma versão inicial para nós (“1.0-SNAPSHOT”). Note que ele configurou a versão como “-SNAPSHOT”, já que é um novo projeto.


Outra coisa que o Maven criou automaticamente foi uma dependência para o “junit”, pois podemos quer testar nosso projeto e precisamos dessa biblioteca em nosso “classpath” de teste.

Ok, mas como eu compilo o projeto?


Simples! Basta ir para a pasta onde está o arquivo “pom.xml” e digitar: “mvn compile”. O Maven vai compilar as classes funcionais (e não as de teste) e criar uma pasta “target”, com esse conteúdo:


projetoteste
|
+-target
  |
  +-classes
    |
    +-com
      |
      +-exemplo
        |
        +-projetoteste
          |
          +-App.class

E você deve ter visto, na janela do “terminal”, o “log” de compilação do Maven, com esse final:

[INFO] Compiling 1 source file to C:\Users\cleuton\target\classes
[INFO] ------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------
[INFO] Total time: 1.232 s
[INFO] Finished at: 2014-06-05T12:55:47-03:00
[INFO] Final Memory: 9M/122M
[INFO] ------------------------------------------------

Essa frase “Build success” é uma das mais bonitas que eu já vi... Dá vontade de chorar! O problema, é que ela não aparece em todo o “build”...

Você deve ter notado que a classe de teste (“src/test/java...”) não foi compilada, certo? Isso pode ser remediado com a fase “test-compile”, ou então mandando o maven testar o nosso projeto.


Empacotando o artefato

Agora, rode o comando “mvn clean package” e observe o resultado:

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.exemplo.projetoteste.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.006 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ projetoteste ---
[INFO] Building jar: C:\Users\cleuton\cursomaven\projetoteste\target\projeto
teste-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.190 s
[INFO] Finished at: 2014-06-05T13:01:24-03:00
[INFO] Final Memory: 12M/127M

[INFO] ------------------------------------------------------------------------

Ele compilou e executou os testes usando o plugin “surefire”, que roda testes Junit. Como nosso projeto tem uma classe de teste (dentro de “src/test/java...”), ele a executou. Legal, não?



Nós encadeamos 2 fases, executadas em sequência: “clean”, que limpa a pasta “target”, e “package”, que:
  • Valida o “pom.xml”;
  • Compila as classes funcionais, se não estiverem compiladas;
  • Compila as classes de teste (fase “test-compile”);
  • Executa os testes;
  • Se tudo der certo, cria um “jar” e coloca na pasta “target”.


Por que ele criou um “jar”? Porque o “packaging” do nosso projeto especificou isso. Procure no “pom.xml” e verá: “<packaging>jar</packaging>”. Ao criar o “jar”, ele deu o nome do “artifactId” e da versão, logo, ficou: “projetoteste-1.0-SNAPSHOT.jar”.


Repositório Maven

Você deve ter notado que o Maven fez alguns “downloads” de artefatos, não? O “log” está cheio deles, principalmente na primeira vez que você rodar alguma das fases. Ele está indo nos repositórios remotos, entre eles o Repositório Central do Maven (“http://mvnrepository.com”), e baixando tudo o que não existe no Repositório Local. Mas onde fica esse “Repositório Local”?


Todas as dependências do seu Projeto Maven ficam armazenadas no repositório de artefatos Maven local, da sua conta. Esse repositório fica dentro da pasta oculta “.m2”, que fica dentro de:
  • Linux / Mac: pasta “home” do usuário que está logado;
  • Windows: C:\Usuários\<seu usuário>;



Abra essa pasta e veja o que tem dentro:


Por exemplo, vamos pesquisar o “Junit”, que é nossa dependência:

Os artefatos ficam armazenados em pastas, de acordo com o “groupId”, “artifactId” e “version”.



É do repositório local que o Maven usa as dependências necessárias para compilar seu projeto. Ele as coloca no “classpath” de compilação, e, quando é necessário testar, no “classpath” de teste. Ele não as copia para dentro do seu projeto, a não ser que ele seja um “war”, neste caso, ele copia para dentro da pasta “WEB-INF/lib”.


Vamos colocar seu Artefato no repositório!

Na janela “terminal”, na pasta onde está o “pom.xml”, rode o comando: “mvn clean install” e veja o resultado:


-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.exemplo.projetoteste.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.006 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ projetoteste ---
[INFO] Building jar: C:\Users\cleuton\cursomaven\projetoteste\target\projeto
teste-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ projetoteste ---

[INFO] Installing C:\Users\cleuton\cursomaven\projetoteste\target\projetotes
te-1.0-SNAPSHOT.jar to C:\Users\cleuton\.m2\repository\com\exemplo\projetote
ste\projetoteste\1.0-SNAPSHOT\projetoteste-1.0-SNAPSHOT.jar
[INFO] Installing C:\Users\cleuton\cursomaven\projetoteste\pom.xml to C:\Use
rs\cleuton\.m2\repository\com\exemplo\projetoteste\projetoteste\1.0-SNAPSHOT
\projetoteste-1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.197 s
[INFO] Finished at: 2014-06-05T13:16:23-03:00
[INFO] Final Memory: 13M/154M

[INFO] ------------------------------------------------------------------------

Ele fez tudo o que o “package” fez, e, ainda por cima, copiou o “jar” para dentro do seu repositório local (a pasta “.m2/repository”). E, se formos “fuçar” no repositório, vamos achar o caminho: “com/exemplo/projetoteste/projetoteste/1.0-SNAPSHOT”. A partir de agora, nosso Artefato pode ser usado como dependência em outros Projetos Maven.



Você notou que, tanto no “package” como no “install”, eu usei o “clean” antes? Isso é para garantir que o código-fonte seja recompilado.


Transformando um projeto normal em Maven

Transformar um projeto normal em Maven é fácil, porém, requer um certo trabalho. É isso o que precisamos fazer:
  1. Criar o projeto vazio (com o “mvn archetype:generate”). Pode usar o arquétipo “maven-quickstart-archetype” mesmo);
  2. Copiar o código-fonte funcional para dentro da pasta “src/main/java”;
  3. Copiar arquivos de configuração e propriedades para “src/main/resources”;
  4. Copiar o código-fonte de teste para dentro da pasta “src/test/java”;
  5. Buscar as dependências usando o site “http://mvnrepository.com”;
  6. Configurar o “pom.xml” com as coordenadas das dependências;
  7. Instalar as dependências que não estejam no Repositório Central Maven;
  8. Eliminar pastas “lib” que, porventura existam no Projeto.


Recursos
Um projeto, geralmente, possui arquivos que não são código-fonte, como:
  • Arquivos de propriedades (log4j etc);
  • Arquivos de configuração, em XML (Hibernate etc);
  • Imagens.


Estes arquivos devem ser carregados na raiz do “classpath”, para que você possa usá-los dentro do projeto Java. O Maven tem uma pasta padrão para isso: “src/main/resources”, onde você deve colocar os arquivos.
Estes recursos serão copiados para dentro da pasta “target/classes”, mantendo a mesma estrutura de diretórios em que eles estão.
Se você tiver versões diferentes de recursos para testes, então pode colocá-los na pasta “src/test/resources”. Quando for executado o teste, o Maven irá primeiro nessa pasta, antes de procurar na “src/main/resources”.



Pesquisando dependências

O repositório central do Maven não permite que pesquisemos nada nele. Então, usamos o site “http://mvnrepository.com” para fazer isso. Por exemplo, pesquisei por “Hibernate”:


Ele apresenta as dependências de acordo com suas “Coordenadas Maven”, e podemos escolher qual versão desejamos. Depois, ele nos mostra a configuração da dependência pronta para ser copiada e colada no “pom.xml”, dentro do tag “<dependencies>”.
E se a dependência não existir no repositório?
É bem difícil que isso aconteça... Porém, pode ser que exista um “jar” seu, que não foi enviado para o Repositório Central, então, temos as seguintes opções:
  1. Se tivermos acesso ao código-fonte do “jar”, podemos convertê-lo em um Projeto Maven e instalá-lo no Repositório Local;
  2. Se não tivermos acesso ao código-fonte, então podemos instalar o “jar”, com um “pom.xml” criado automaticamente, usando o comando: “mvn install:install-file”;



mvn install:install-file -Dfile=your-artifact-1.0.jar \
                         [-DpomFile=your-pom.xml] \
                         [-Dsources=src.jar] \
                         [-Djavadoc=apidocs.jar] \
                         [-DgroupId=org.some.group] \
                         [-DartifactId=your-artifact] \
                         [-Dversion=1.0] \
                         [-Dpackaging=jar] \
                         [-Dclassifier=sources] \
                         [-DgeneratePom=true] \
                         [-DcreateChecksum=true]



E como eu uso no Eclipse?

Boa pergunta! O Eclipse “Kepler” para desenvolvedores Java EE, já vem pronto para usar o Maven. Se você tem uma outra versão, então, pode ser necessário instalar o plugin “m2e” no Eclipse. É só instalar a partir do “update site”, que pode ser pesquisado em: http://eclipse.org/m2e/download/.


Para saber se você tem o “m2e”, é só abrir a Janela “Window / Preferences” e ver se tem uma opção “maven”.



Você pode, inclusive, importar o projeto que acabou de criar para dentro do Eclipse: “file / import / maven / Existing maven projects” e selecionar a pasta que contém a pasta do seu projeto.


Note que o “m2e” tem um editor “bonitinho” para o “pom.xml”, que nos apresenta as dependências e até a sua hierarquia.



Antes de compilar seu projeto Maven no Eclipse, temos que configurar a Workspace para usar a nossa instalação do Maven. O “m2e” usa um “maven embedded” com versão 3.0.4, que não é a versão que estamos usando. Para isto, abra o menu “window / preferences”, selecione “maven” e “installations”, e acrescente a pasta onde instalou o Maven 3.2.1:


Agora você vai usar o Maven correto! Só falta uma coisinha: verificar se o Eclipse está usando uma JDK! Abra o menu “window / preferences” e selecione “Java” e depois “installed JREs”. Se estiver rodando em uma JRE (o Eclipse tem compilador próprio) aponte para uma JDK:


Clique com o botão direito sobre o seu projeto e selecione “Run As Maven build...”:


Então, você vai conseguir executar um “clean install” exatamente como fizemos no “terminal”, e o “log” aparece na “view” “console”.



Vários “goals” padrões do Maven já estão configurados no menu de contexto (Run as). Só falta uma coisinha para fecharmos a lição: O menu “Maven”:


Ao clicar com o botão direito sobre o projeto, você deve ter notado um menu “maven...”. Este menu tem várias opções interessantes, que permitem adicionar dependências, plugins etc. O item mais importante é o “Update Project...”.


Quando criamos um projeto Maven no Eclipse, ele cria uma “pasta” chamada “Maven dependencies” e organiza todas as suas dependências, que estão no repositório local. Bem, se você mudar alguma coisa no “pom.xml”, essa lista fica desatualizada, então, você pode usar o “Update project” para reconfigurar isso. Sempre que você alterar o “pom.xml”, seja para o que for, rode um “Update dependencies”.



Ah, e muito importante: Se o seu projeto é Maven, não use mais “Project / clean”! Use sempre: “Run As Maven Clean”, assim como “Run As Maven Package”.

Exercício

Bom, vamos ver se você aprendeu alguma coisa... Baixe o projeto que está no zip “exercicio-licao1.zip”. Descompacte, converta para Maven e instale no seu Repositório Local. Só isso.
A resposta está no zip “resposta-licao1.zip”, caso você peça “penico”.


Porém, antes de pedir “penico”, leia as dicas que eu vou dar:


  1. Use o Eclipse, pois fica mais fácil;
  2. Crie uma Workspace e lembre-se de mudar 2 coisas:
    1. Aponte a JRE do Eclipse para sua JDK (“window / preferences”, depois “Java” e “installed JREs”);
    2. Aponte o Maven para a sua instalação (“window / preferences”, depois “Maven” e “installations”);
  3. Crie um projeto Maven no próprio Eclipse (“file / new / other”, depois “Maven” e “Maven Project”). Use o arquétipo “maven-archetype-quickstart”. É simples, ele vai aparecer na lista de arquétipos;
  4. Para o “groupId”, use o nome do pacote java das classes que estão em “src”, e para “artifactId”, use “WormJoint”;
  5. Pode dar um problema com o pacote, pois o plugin “m2e” vai criar um pacote contendo o “groupId” e o “artifactId”, o que está diferente das classes. Você escolhe: ou muda as classes de pacote ou renomeia os pacotes gerados. É com você!
  6. Importe a classe “WormJoint.java” para “src/main/java/...” e a classe “TesteWJ.java” para “src/test/java...”;
  7. Abra a pasta “lib” e anote todos os “jars” que estão lá. Você deverá procurar as dependências no site “http://mvnrepository.com”. Para facilitar, o número da versão já está no nome dos “jars;
  8. Uma dica quanto ao FEST: Há um pacote que já tem todos os outros como dependências, logo, você só precisa procurar um só, que é: “fest-swing”;
  9. Eu recomendo que você coloque três propriedades no seu “pom.xml”:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
</properties>


A propriedade “project.build.sourceEncoding” diz a codificação de caracteres utilizada no código-fonte. Use sempre “utf-8” e acostume-se a isso. Quando você estiver usando o Eclipse, pode setar isso em “window / preferences” e “Editors”, alterando o “Character Encoding” do editor de arquivos textuais.


As propriedades “maven.compiler.source” e “maven.compiler.target” alteram o valor de “-source” e “-target” passados para o plugin de compilação. Coloque sempre a versão do Java que pretende usar.


Acompanhe as lições do curso Maven Pro:

http://www.obomprogramador.com/p/cursos.html

Aproveite e use o Maven profissionalmente


http://www.obomprogramador.com/p/livros.html#qualidade