Skip to content

3. As ferramentas do documento

Os exemplos deste documento foram testados com as seguintes ferramentas:

  • NetBeans, da versão 6.8 à versão 7.1.2. A instalação do NetBeans está descrita no [ref3], no parágrafo 1.3.1.
  • Wampserver versão 2.2. A instalação do WampServer está descrita no [ref3], no parágrafo 1.3.3;
  • O Maven está integrado ao NetBeans. A seguir, descreveremos essa ferramenta.

3.1. Maven

3.1.1. Introdução

O Maven está disponível no URL [http://maven.apache.org/index.html ]. Segundo seus criadores:

O objetivo principal do Maven é permitir que um desenvolvedor compreenda o estado completo de um projeto de desenvolvimento no menor tempo possível. Para atingir esse objetivo, há várias áreas de interesse que o Maven procura abordar:

  • Simplificar o processo de compilação
  • Fornecer um sistema de compilação uniforme
  • Fornecer informações de qualidade sobre o projeto
  • Fornecer diretrizes para o desenvolvimento com base nas melhores práticas
  • Permitir a migração transparente para novos recursos

O Maven está integrado ao NetBeans e vamos utilizá-lo apenas para uma de suas funcionalidades: o gerenciamento das bibliotecas de um projeto. Essas bibliotecas são compostas pelo conjunto de arquivos jars, que devem estar localizados no diretório Classpath do projeto. Elas podem ser em grande número. Por exemplo, nossos projetos futuros utilizarão o ORM (Mapeador Objeto-Relacional) Hibernate. Esse ORM é composto por dezenas de arquivos jar. A vantagem do Maven é que ele nos dispensa de conhecer todos eles. Basta indicarmos em nosso projeto que precisamos do Hibernate, fornecendo todas as informações necessárias para localizar o arquivo principal desse ORM. O Maven, então, também baixa todas as bibliotecas necessárias para o Hibernate. Isso é chamado de dependências do Hibernate. Uma biblioteca necessária para o Hibernate pode, por sua vez, depender de outros arquivos. Esses também serão baixados. Todas essas bibliotecas são colocadas em uma pasta chamada repositório local do Maven.

Um projeto Maven é facilmente compartilhável. Se ele for transferido de um computador para outro e as dependências do projeto não estiverem presentes no repositório local do novo computador, elas serão baixadas.

O Maven pode ser usado sozinho ou integrado a um IDE (Ambiente de Desenvolvimento Integrado), como o NetBeans ou o Eclipse.

Vamos criar um projeto Maven no NetBeans:

  • no [1], crie um novo projeto,
  • em [2], selecione a categoria [Maven] e o tipo de projeto [Java Application],
  • em [3], indicar a pasta pai da pasta do novo projeto,
  • em [4], nomeie o projeto,
  • em [5], o projeto gerado.

Vamos examinar os elementos do projeto e explicar a função de cada um.

  • em [1]: os diferentes ramos do projeto:
    • [Source packages]: as classes Java do projeto;
    • [Test packages]: as classes de teste do projeto;
    • [Dependencies]: os arquivos .jar necessários ao projeto e gerenciados pelo Maven;
    • [Test Dependencies]: os arquivos .jar necessários para os testes do projeto e gerenciados pelo Maven;
    • [Java Dependencies]: os arquivos .jar necessários para o projeto e não gerenciados pelo Maven;
    • [Project Files]: arquivos de configuração do Maven e do NetBeans,
  • em [3], o ramo [Source Packages],

Este branch contém os códigos-fonte das classes Java do projeto. O NetBeans gerou uma classe por padrão:


package istia.st.mvexemple;

/**
 * Hello world!
 * 
 */
public class App {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
  • em [4], o ramo [Test Packages], que contém os códigos-fonte das classes de teste do projeto,
  • em [5], a biblioteca JUnit 3.8 necessária para a execução dos testes,

O NetBeans gerou uma classe padrão:


package istia.st.mvexemple;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * Unit test for simple App.
 */
public class AppTest extends TestCase {
    /**
     * Create the test case
     * 
     * @param testName
     *          name of the test case
     */
    public AppTest(String testName) {
        super(testName);
    }

    /**
     * @return the suite of tests being tested
     */
    public static Test suite() {
        return new TestSuite(AppTest.class);
    }

    /**
     * Rigourous Test :-)
     */
    public void testApp() {
        assertTrue(true);
    }
}

Este é um teste JUnit 3.8. Posteriormente, utilizaremos testes JUnit 4.x.

  • no [6], o ramo [Dependencies] está vazio aqui,

Este ramo exibe todas as bibliotecas necessárias ao projeto e gerenciadas pelo Maven. Todas as bibliotecas listadas aqui são baixadas automaticamente pelo Maven. É por isso que um projeto Maven precisa de acesso à Internet. As bibliotecas baixadas serão armazenadas localmente. Se outro projeto precisar de uma biblioteca já presente localmente, ela não será baixada. Veremos que essa lista de bibliotecas, bem como os repositórios onde elas podem ser encontradas, são definidos no arquivo de configuração do projeto Maven.

  • em [7], as bibliotecas necessárias ao projeto e não gerenciadas pelo Maven,
  • em [7], o arquivo [pom.xml] de configuração do projeto Maven. POM significa Project Object Model. Teremos que intervir diretamente nesse arquivo.

O arquivo [pom.xml] gerado é o seguinte:


<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>istia.st</groupId>
  <artifactId>mv-exemple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>mv-exemple</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
  • as linhas 5 a 8 definem o objeto (artefato) Java que será criado pelo projeto Maven. Essas informações provêm do assistente utilizado durante a criação do projeto:

Um objeto Maven é definido por quatro propriedades:

  • [groupId]: uma informação que se assemelha a um nome de pacote. Assim, as bibliotecas do framework Spring têm groupId=org.springframework; as do framework JSF têm groupId=javax.faces,
  • [artifactId]: o nome do objeto Maven. No grupo [org.springframework], encontramos, portanto, os seguintes artifactId: spring-context, spring-core, spring-beans, ... No grupo [javax.faces], encontramos o artifactId e o jsf-api,
  • [version]: número da versão do artefato Maven. Assim, o artefato org.springframework.spring-core possui as seguintes versões: 2.5.4, 2.5.5, 2.5.6, 2.5.6.SECO1, ...
  • [packaging]: o formato do artefato, geralmente war ou jar.

Nosso projeto Maven irá gerar um [jar] (linha 8) no grupo [istia.st] (linha 5), denominado [mv-exemple] (linha 6) e com a versão [1.0-SNAPSHOT] (linha 7). Essas quatro informações devem definir de forma única um artefato Maven.

As linhas 17 a 24 listam as dependências do projeto Maven, ou seja, a lista das bibliotecas necessárias ao projeto. Cada biblioteca é definida por quatro informações (groupId, artifactId, versão, pacote). Quando a informação packaging está ausente, como neste caso, é utilizado o arquivo JAR packaging. Acrescenta-se outra informação, o escopo (scope), que determina em quais momentos do ciclo de vida do projeto a biblioteca é necessária. O valor padrão é “compile”, o que indica que a biblioteca é necessária para a compilação e a execução. O valor “test” significa que a biblioteca é necessária durante os testes do projeto. É o caso aqui com a biblioteca JUnit 3.8.1. Se essa biblioteca não estiver presente no repositório local da estação de trabalho, ela será baixada.

3.1.2. Execução do projeto

Executamos o projeto:

No [1], o projeto Maven é compilado e, em seguida, executado no [1]. Os logs no console do NetBeans são os seguintes:

Scanning for projects...
...

------------------------------------------------------------------------
Building mv-exemple 1.0-SNAPSHOT
------------------------------------------------------------------------

[resources:resources]
[debug] execute contextualize
Using 'UTF-8' encoding to copy filtered resources.
skip non existing resourceDirectory D:\data\istia-1112\netbeans\glassfish\mv-pam\00\mv-exemple\src\main\resources

[compiler:compile]
Compiling 1 source file to D:\data\istia-1112\netbeans\glassfish\mv-pam\00\mv-exemple\target\classes

[exec:exec]
Downloading: http://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.0.1/commons-exec-1.0.1.pom

Downloaded: http://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.0.1/commons-exec-1.0.1.pom (8 KB a 113,5 KB/seg)
Downloading: http://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.0.1/commons-exec-1.0.1.jar

Downloaded: http://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.0.1/commons-exec-1.0.1.jar (49 KB a 763,6 KB/seg)
Hello World!
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time: 4.040s
Finished at: Thu Jun 21 10:10:40 CEST 2012
Final Memory: 13M/122M

O resultado está na linha 23. Percebe-se que, mesmo nesse caso simples, o Maven baixou alguns elementos (linhas 17 e 20).

3.1.3. O sistema de arquivos de um projeto Maven

  • [1]: o sistema de arquivos do projeto está na aba [Files],
  • [2]: os códigos-fonte Java estão na pasta [src / main / java],
  • [3]: os códigos-fonte Java dos testes estão na pasta [src / test / java],
  • [4]: a pasta [target] é criada durante a compilação do projeto,
  • [5]: aqui, a compilação do projeto criou um arquivo [mv-exemple-1.0-SNAPSHOT.jar].

3.1.4. O repositório local do Maven

Já mencionamos que o Maven baixa as dependências necessárias para o projeto e as armazena localmente. É possível explorar esse repositório local:

  • em [1], seleciona-se a opção [Window / Other / Maven Repository Browser],
  • em [2], abre-se uma aba [Maven Repositories],
  • em [3], ele contém dois ramos: um para o repositório local e outro para o repositório central. Este último é gigantesco. Para visualizar seu conteúdo, é preciso atualizar seu índice [4]. Essa atualização leva várias dezenas de minutos.
  • em [5], as bibliotecas do repositório local,
  • em [6], encontramos um ramo [istia.st] que corresponde ao [groupId] do nosso projeto,
  • em [7], acessa-se as propriedades do repositório local,
  • em [8], temos o caminho do repositório local. É útil conhecê-lo, pois, às vezes (raramente), o Maven deixa de usar a versão mais recente do projeto. Fazemos alterações e percebemos que elas não são incorporadas. Podemos, então, excluir manualmente o ramo do repositório local correspondente ao nosso [groupId]. Isso força o Maven a recriar o ramo a partir da versão mais recente do projeto.

3.1.5. Pesquisar um artefato com o Maven

Vamos aprender agora a procurar um artefato com o Maven. Comecemos pela lista de dependências atuais do arquivo [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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>istia.st</groupId>
  <artifactId>mv-exemple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>mv-exemple</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

As linhas 17 a 23 definem dependências que vamos modificar para usar as bibliotecas em suas versões mais recentes.

Primeiramente, removemos as dependências atuais [1]. O arquivo [pom.xml] é então modificado:


<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>istia.st</groupId>
  <artifactId>mv-exemple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>mv-exemple</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies></dependencies>
</project>

Na linha 17, a dependência removida não aparece mais no [pom.xml]. Agora, vamos procurá-la nos repositórios do Maven.

  • em [1], adiciona-se uma dependência ao projeto,
  • no [2], é necessário especificar informações sobre o artefato procurado (groupId, artifactId, versão, empacotamento (Tipo) e escopo). Começamos especificando o [groupId] [3],
  • em [4], digitamos [espace] para exibir a lista de artefatos possíveis. Aqui, [junit] e [jnit-dep]. Escolhemos [junit],
  • em [5], seguindo o mesmo procedimento, escolhemos a versão mais recente. O tipo de empacotamento é jar,
  • e, em [6], escolhemos o escopo “teste” para indicar que a dependência é necessária apenas para os testes.

Em [6], as dependências adicionadas aparecem no projeto. O arquivo [pom.xml] reflete essas alterações:


<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>istia.st</groupId>
  <artifactId>mv-exemple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>mv-exemple</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
      <type>jar</type>
    </dependency>
  </dependencies>
</project>

Observe que o arquivo [pom.xml] não menciona a dependência [hamcrest-core-1.1] que vemos no [6]. Isso ocorre porque se trata de uma dependência do JUnit 4.10 e não do próprio projeto. Isso é indicado por um ícone diferente no ramo [Dependencies]. Ele foi baixado automaticamente.

Suponhamos agora que não conheçamos o [groupId] do artefato que desejamos. Por exemplo, queremos usar o Hibernate como ORM (Mapeador Objeto-Relacional) e isso é tudo o que sabemos. Nesse caso, podemos acessar o site [http://mvnrepository.com/]:

No [1], é possível digitar palavras-chave. Digite hibernate e inicie a pesquisa.

  • no [2], vamos escolher o [groupId], o org.hibernate e o [artifactId], o hibernate-core,
  • em [3], vamos escolher a versão 4.1.2-Final,
  • em [4], obtemos o código Maven para colar no arquivo [pom.xml]. Fazemos isso.

<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>istia.st</groupId>
  <artifactId>mv-exemple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>mv-exemple</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
      <type>jar</type>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>4.1.2.Final</version>
    </dependency>
  </dependencies>
</project>

Salvamos o arquivo [pom.xml]. O Maven então inicia o download das novas dependências. O projeto evolui da seguinte forma:

  • para [5], a dependência [hibernate-core-4.1.2-Final]. No repositório onde foi encontrado, esse [artifactId] também é descrito por um arquivo [pom.xml]. Esse arquivo foi lido e o Maven descobriu que o [artifactId] tinha dependências. Ele também as baixa. Ele fará isso para cada [artifactId] baixado. No final, encontramos no [6] dependências que não havíamos solicitado diretamente. Elas são indicadas por um ícone diferente daquele do [artifactId] principal.

Neste documento, utilizamos o Maven principalmente por causa dessa característica. Isso nos poupa de precisar conhecer todas as dependências de uma biblioteca que queremos usar. Deixamos que o Maven as gerencie. Além disso, ao compartilhar um arquivo [pom.xml] entre desenvolvedores, temos a garantia de que cada desenvolvedor está usando as mesmas bibliotecas.

Nos exemplos a seguir, nos limitaremos a fornecer o arquivo [pom.xml] utilizado. O leitor só precisará utilizá-lo para se encontrar nas mesmas condições que o documento. Além disso, os projetos Maven são reconhecidos pelos principais ambientes de desenvolvimento Java (Eclipse, NetBeans, IntelliJ, JDeveloper). Assim, o leitor poderá usar seu IDE favorito para testar os exemplos.