Pesquisar este blog

segunda-feira, 24 de agosto de 2015

Controlando o seu build no Java com o Maven

Ao desenvolver um software, vamos precisar utilizar bibliotecas, apis e softwares de terceiros. Quanto maior a complexidade do seu projeto, maior será o número de bibliotecas utilizadas como dependência, com isso, o controle das versões e dos arquivos destas dependências torna-se uma tarefa dispendiosa.
Com a evolução dos softwares, o processo de build tornou-se complicado e a sua administração começou a ocupar um bom tempo de esforço do projeto, afim de facilitar esta administração foram criadas algumas ferramentas.
As ferramentas de controle de build, nos ajudam a controlar as dependências do projeto, controlar o conflito de dependências, executar a compilação, e os testes do projeto.
Existem diversas ferramentas que podem te auxiliar na administração do build, a mais usada, e descrita aqui será o Apache Maven. A minha preferida, o SBT, foi descrita neste post.

Estrutura de um projeto maven

O principal arquivo de um projeto maven é o pom.xml. O nome pom vem de PrOject Management, ou administrador de projeto, nele serão definidas as configurações do build, este arquivo deverá estar localizado na pasta raíz do projeto.
A estrutura de pastas de um projeto maven é a seguinte:
  • projeto
    • pom.xml
      • src
        • main
          •  resourcces
          • java
            • pacote
              • App.java
        • test
          • java
            • pacote
              • TestApp.java
Todo código do projeto deverá ficar dentro da pasta src, que vem de source (ou fonte em inglês), sendo que este código pode ser subdividido por linguagens, por isso há umapasta java dentro do diretório src, que é onde ficam os códigos fonte do aplicativo, escritos em java. Já os testes de java devem estar dentro da pasta src/test.
Dentro do diretório resources ficam os arquivos de configuração e metadados do nosso projeto.

Definição de um projeto usando o maven

Um exemplo de pom para o nosso projeto web seria
<project br="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
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>seu.pacote.basico</groupid>
<artifactid>projeto</artifactid>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Projeto web desenvolvido em DSD</name>
<url>http://seusite.com.br</url>

<dependencies>
<dependency>
<groupid>junit</groupid>
<artifactid>junit</artifactid>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

Nas primeiras 3 linhas deste xml estamos definindo o cabeçalho do pom, todo arquivo de xml possui um cabeçalho, isso ajuda os softwares de desenvolvimento e ao maven a identificar quais versões do pom que estão sendo utilizadas nele. As definições do projeto vem logo abaixo:
  • groupId geralmente contém o site da empresa que está desenvolvendo o projeto.
  • artifactId é o nome do projeto que está sendo desenvolvido.
  • name possui uma pequena descrição do projeto
  • url contem o site do projeto
  • dependencies é onde iremos definir as dependencias do projeto
Repare que para definir uma dependência, utilizamos o mesmo padrão de groupId e artifactId que usamos na definiçao do nosso projeto. Caso você queira distribuir o seu projeto em forma de api, basta colocá-lo em algum repositório e mapear este repositório em outro projeto, que o maven se encarregará de baixar esta api e colocá-la dentro do seu projeto.
Administrar as dependências do projeto, é uma das principais funcionalidades do maven, se não tivessemos um administrador de build, deveriamos procurar, baixar e copiar no classpath, todos os jars de libs utilizados em nossos projetos. Além de administrar os conflitos existentes entre eles, o que seria uma tarefa muito tediosa.
Como o maven baixa as dependências dos nossos projetos, não faz sentido fazer isso a todo comando de build, por isso o maven cria um diretório .m2 no seu HOME_FOLDER e faz uma cópia de todos as libs utilizadas em seus projetos dentro deste diretório, com isso ele agiliza o processo de build já que, estando lá, ele não vai precisar baixar novamente uma biblioteca.
Uma outra informação que foi definida para este projeto é o tipo de empacotamento. No exemplo acima temos o formato do arquivo como jar, que é o formato padrão do java. Já em um projeto web, este formato será o war.

Iniciando um projeto Maven

Depois de instalado, para chamar o maven, basta digitar mvn no console da sua máquina, ou no command prompt do windows.
O maven possui um comando usado para criar a estrutura de um projeto, neste comando definimos atributos como o groupId, o attributeId, e o tipo do projeto. Para inicializarmos o nosso projeto web, usaremos o seguinte comando:
mvn archetype:generate -DgroupId={seu-group-id} -DartifactId={seu-artifact-id} -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
Ao executar este comando, o maven irá criar toda a estrutura de um projeto web, assim como o seu pom.xml básico e a estrutura de diretórios de um projeto web.
A estrutura de um projeto web basicamente é a mesma de um projeto java, porém ela irá conter mais dois diretórios para armazenar as informações referentes a web.
  1. projeto
  2. |-- pom.xml
  3. |`-- src
  4. |`-- |`-- main
  5. |`-- |`-- resources
  6. |`-- |`-- webapp
  7. |`-- |`-- |`--   WEB-INF
  8. |`-- |`-- |`--   web.xml
  9. |`-- |`-- |`--   index.jsp
  10. |`-- |`-- java
  11. |`-- |`-- |`--   pacote
  12. |`-- |`-- |`--|`--    App.java
  13. |`-- |`-- test
  14. |`-- |`-- |`-- java
  15. |`-- |`-- |`--|`-- pacote
  16. |`-- |`-- |`--|`--|`-- AppTest.java
Dentro do diretório webapp teremos os nossos arquivos de UI, como exemplo o index.jsp. e no diretório WEB-INF contem informações que serão acessíveis pelo seu código java, mas que não serão publicadas, ou seja, não poderão ser acessadas diretamente pelo usuário.

Resultado da execução de um comando

Toda vez que executarmos um comando do maven, ele irá nos mostrar um log de resultado, como o mostrado abaixo:
 [INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-webapp:1.0
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: basedir, Value: /home/dirceu/projects/dsdweb
[INFO] Parameter: package, Value: br.unip
[INFO] Parameter: groupId, Value: br.unip
[INFO] Parameter: artifactId, Value: dsd-web
[INFO] Parameter: packageName, Value: br.unip
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /home/dirceu/projects/dsdweb/dsd-web
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 02:04 min
[INFO] Finished at: 2015-08-23T23:50:16-03:00
[INFO] Final Memory: 12M/93M
[INFO] ------------------------------------------------------------------------
BUILD SUCCESS significa que o nosso comando rodou sem problemas.
Qualquer erro que aconteça durante o processo de build, resultará em uma mensagem com um:
BUILD FAILURE
e o motivo da falha será explicado com mensagens de erros, conforme mostrado abaixo:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 40.229 s
[INFO] Finished at: 2015-08-24T00:06:34-03:00
[INFO] Final Memory: 15M/98M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-archetype-plugin:2.4:generate (default-cli) on project standalone-pom: Directory dsdweb already exists  - please run from a clean directory -> [Help 1]
Repare que a explicação do erro está grifada, como o diretório já existe ele não conseguiu criar um projeto.

Argumentos de build do Maven

Para fazermos um build, não basta chamar o comando mvn, devemos passar alguns argumentos para definir o que queremos fazer com o nosso projeto.
Ao executar o maven, você deverá dizer a ele o que fazer, a seguir serão mostrados os comandos disponíveis no maven:
  • validate - valida se todas as informações do projeto estão disponíveis
  • compile - compila o projecto
  • test - executa os testes do projeto
  • package - pega o código compilado do projeto e cria o arquivo para distribuí-lo, no formato definido pela configuração.
  • integration-test - faz um deploy do pacote em um ambiente onde pode ser rodado os testes de integração
  • verify - roda qualquer checagem necessária para assegurar que o projeto atende a todos os requisitos de qualidade
  • install - instala o pacote em um repositório local
  • deploy - copia o pacote final para o repositório onde ele será distribuído
Entenda que estes comandos possuem dependências entre eles, por exemplo, não faz sentido inicializarmos a compilação, se o projeto não passou pela validação. Por isso quando você digita qualquer um destes comandos, o maven verifica as suas dependencias e, se você se esqueceu de alguma, ele irá executá-la automaticamente.
Para gerarmos um arquivo do nosso projeto, podemos fazer:
  • mvn package 
  • mvn validate test compile package

 Encontrando dependências

Quando estamos desenvolvendo um projeto, uma dúvida recorrente é onde e como encontrar as dependências. Geralmente no website dos projetos, eles já nos disponibilizam qual será o texto que devemos colar para adicinar alguma dependencia ao nosso projeto.
Os conteúdos das bibliotecas são distribuídos em repositórios, e a apache possui um repositório central, que já vem configurado por padrão. Todas as bibliotecas e apis que estiverem definidas lá, podem ser adicionadas ao seu projeto sem problemas. No site dele você pode procurar por apis, e ele te mostra quais são as versões disponíveis, além do texto a ser colocado no seu pom.xml para adicionar aquela biblioteca.
Quando o maven não encontrar alguma biblioteca que você adicionou, é por que ela não está armazenada neste repositório, neste caso você deverá procurar pela internet, onde é que aquela biblioteca está armazenada.

Nenhum comentário:

Postar um comentário