Introdução

Maven é uma plavra derivada da Língua iídiche, que significa, acumulador de conhecimento.

Apache Maven não é apenas um gerenciador de dependências, mais sim um gerenciador de projetos, é uma ferramenta que pode ser usada para criar (build) e gerenciar qualquer projeto baseado em Java.

Para mais informações sobre a história do maven, verifique o site: Apache Maven

Instalação

Instalação da ferramenta Maven é bem simples de se realizar, no momento atual do curso a versão mais recente é a 3.6.2.

Comandos e instruções abaixo são para sistema Linux baseado na distrubuição Ubuntu.
  1. Pré-Requisitos:

    • Ferramenta para desempacotamento de arquivos tar.gz.

    • Java JDK 1.8 instalado com JAVA_HOME configurado.

  2. Realizar o download da ferramenta

    • Abrir terminal do Linux ctrl+shit+t e acessar pasta home do usuário cd ~

    • Executar o comando abaixo para fazer o download.

      curl -o apache-maven-bin.tar.gz http://ftp.unicamp.br/pub/apache/maven/maven-3/3.6.2/binaries/apache-maven-3.6.2-bin.tar.gz
    • Executar o comando abaixo para extrair o conteúdo do arquivo apache-maven-bin.tar.gz em uma pasta.

      tar -xzf apache-maven-bin.tar.gz
    • Valide se o processo de download e desempacotamento está OK com o comando abaixo:

      ./apache-maven-3.6.2/bin/mvn -v

      Esse comando vai apresentar uma saída no terminal semelhante a que está abaixo:

      Apache Maven 3.6.2 (40f52333136460af0dc0d7232c0dc0bcf0d9e117; 2019-08-27T12:06:16-03:00)
      Maven home: /home/felipe/maven-teste/apache-maven-3.6.2
      Java version: 1.8.0_201, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-8-oracle/jre
      Default locale: pt_BR, platform encoding: UTF-8
      OS name: "linux", version: "4.15.0-66-generic", arch: "amd64", family: "unix"

      Caso a saída seja semelhante a essa abaixo o seu JDK não foi instalado/configurado corretamente.

      The JAVA_HOME environment variable is not defined correctly
      This environment variable is needed to run this program
      NB: JAVA_HOME should point to a JDK not a JRE
  3. Realizar a configuração de execução via terminal.

    Para essa configuração, vamos gerar um arquivo que vai sempre configurar o executável do maven: mvn para ser chamado na linha de comando sem a necessidade de lista o caminho completo.

    • Criar uma arquivo chamado maven.sh com um editor de texto, pode ser o gedit do Ubuntu: gedit maven.sh.

      Adicionar o conteúdo abaixo no arquivo e salvar, trocando o SEU-USUARIO para o valor correto do seu usuário Home.

      export M2_HOME=/home/SEU-USUARIO/apache-maven-3.6.2
      export PATH=${M2_HOME}/bin:${PATH}
    • Mover o arquivo maven.sh com o comando abaixo.

      sudo mv maven.sh /etc/profile.d/maven.sh

      Esse arquivo será lido na inicialização do sistema e configura o executável corretamente para ser usado via terminal.

    • Realize o logout da sua coonta ou reinicie a máquina e para validar instalação executamos o mesmo comando do passo 2 sem precisar indicar o caminho completo.

      mvn -v

      A saída deve ser semelhante a anterior.

      Apache Maven 3.6.2 (40f52333136460af0dc0d7232c0dc0bcf0d9e117; 2019-08-27T12:06:16-03:00)
      Maven home: /home/felipe/maven-teste/apache-maven-3.6.2
      Java version: 1.8.0_201, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-8-oracle/jre
      Default locale: pt_BR, platform encoding: UTF-8
      OS name: "linux", version: "4.15.0-66-generic", arch: "amd64", family: "unix"

Para mais informações sobre instalação do Maven, verifique o site: Apache Maven Install

Maven Arquivos Configuração

Maven possui alguns arquivos de configuração importantes, vamos destacar 2 deles: pom.xml e o settings.xml

Maven Settings.xml

O arquivo settings.xml é usado para definir configurações globais para ferramenta Maven.

Algumas mais comuns são:

  • Caminho do repositório local.

  • Miror do repositório remoto padrão do maven.

  • Profiles padrão.

  • Servidores (repositories e pluginsRepositories).

O arquivo é lido pelo executável do maven em 2 lugares, são eles:

  • conf/settings.xml

    • Localiazada dentro da pasta Home de instalação do maven.

  • .m2/settings.xml

    • Localiazada na pasta Home do Usuário autenticado no Linux

Caso os 2 arquivos existam ao mesmo tempo, e feito um mesclagem entre as configuraçoes dos 2 arquivos durante a execução de algum BUILD do maven.

Recomentado é se colocar o settings.xml dentro da pasta .m2 do home do usuário visando compartilhar as configurações entre todas as instalações de maven do seu computador. Veja o que é melhor no seu dia a dia para configuração.

Para mais informações sobre o arquivo settings.xml e o que pode ser alterado, verifique o site: Apache Maven Settings Reference

Exercício 1

  1. Criar/editar o arquivo settings.xml da pasta conf da instalação do maven com o conteúdo abaixo:

    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                              https://maven.apache.org/xsd/settings-1.0.0.xsd">
          <localRepository>${user.home}/repositorio-maven-conf</localRepository>
    </settings>
    • Acessar a pasta de treinamento_codigo_fonte do projeto e executar o comando maven abaixo 2 vezes e depois verificar a pasta repositorio-maven-conf gerada no diretório do usuário.

      mvn dependency:tree
  2. Apagar a pasta repositorio-maven-conf gerada anteriormente.

  3. Criar/editar o arquivo settings.xml da pasta .m2 do home do seu usário:

    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                              https://maven.apache.org/xsd/settings-1.0.0.xsd">
          <localRepository>${user.home}/repositorio-maven-m2</localRepository>
    </settings>
    • Acessar a pasta de treinamento_codigo_fonte do projeto e executar o comando maven abaixo 2 vezes e depois verificar a pasta repositorio-maven-conf gerada no diretório do usuário.

      mvn dependency:tree

Temos um exemplo clásico de como se comporta a configuração mesclada entre os settings.xml. O arquivo do .m2 trocou o repositório padrão.

Agora repita o exercício anterior usando as configuraçoẽs abaixo

  • Arquivo da pasta conf

    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                              https://maven.apache.org/xsd/settings-1.0.0.xsd">
          <localRepository>${user.home}/repositorio-maven-conf</localRepository>
          <mirrors>
            <mirror>
              <id>mirror</id>
              <name>Mirror de Teste</name>
              <url>http://element.basis.com.br/repository/maven-public/</url>
              <mirrorOf>central</mirrorOf>
            </mirror>
          </mirrors>
    </settings>
  • Arquivo da pasta .m2

    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                              https://maven.apache.org/xsd/settings-1.0.0.xsd">
          <localRepository>${user.home}/repositorio-maven-m2</localRepository>
          <mirrors>
            <mirror>
              <id>mirror</id>
              <name>Mirror de Teste</name>
              <url>http://element.basis.com.br/repository/public/</url>
              <mirrorOf>central</mirrorOf>
            </mirror>
          </mirrors>
    </settings>

Template Settings.xml

Muitas propriedades podem ser configuradas no arquivo setttings.xml, vamos listar abaixo e explicar um pouco sobre cada parte do arquivo.

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      https://maven.apache.org/xsd/settings-1.0.0.xsd">
  <localRepository/>
  <interactiveMode/>
  <offline/>
  <pluginGroups/>
  <servers/>
  <mirrors/>
  <proxies/>
  <profiles/>
  <activeProfiles/>
</settings>
Propriedades Simples
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      https://maven.apache.org/xsd/settings-1.0.0.xsd">
  <localRepository>/caminho/completo/para/pasta/no/meu/disco</localRepository>
  <interactiveMode>true</interactiveMode>
  <offline>false</offline>
  ...
</settings>
  • localRepository

    • Caminho no Disco onde o maven usa em tempo de build para instalar / armazenar os artefatos (jar, war, ear, zip) em tempo de build. valor padrão ${user.home}/.m2/repository

  • interactiveMode

    • Valor true | false indica em momento de build, se maven deve esperar por alguma resposta do usuaŕio, ou falhar caso alguma informação obrigatória não foi enviada no comando de build. Padrão é true.

  • offline

    • Valor true | false para o maven travalhar offline, ou seja, ter acesso a obter artefatos de repositórios na WEB ou usar somente o repositório local. Vaor padrão é false.

Propriedade "Plugin Groups"
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      https://maven.apache.org/xsd/settings-1.0.0.xsd">
  ...
  <pluginGroups>
    <pluginGroup>org.eclipse.jetty</pluginGroup>
  </pluginGroups>
  ...
</settings>

Essa propriedade deve ser preenhcida com o valor do groupId (veremos depois mo pom.xml) facilitando no processo de build.

No exemplo, caso você não use o pluginGroup para executar um comando do plugin do Jetty devemos usar o comando completo: org.eclipse.jetty:jetty-maven-plugin:run

Quando configuramos o pluginGroup podemos usar o comando de forma mais simples: jetty:run, bem mais simples!!! Vantagem que é compartilhado para todos os seus projetos maven.

Propriedade "Servers"
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      https://maven.apache.org/xsd/settings-1.0.0.xsd">
  ...
  <servers>
    <server>
      <id>server001</id>
      <username>my_login</username>
      <password>my_password</password>
      <privateKey>${user.home}/.ssh/id_dsa</privateKey>
      <passphrase>some_passphrase</passphrase>
      <filePermissions>664</filePermissions>
      <directoryPermissions>775</directoryPermissions>
      <configuration>...</configuration>
    </server>
  </servers>
  ...
</settings>

Serve para armazenar as configurações que não são interessantes de serem incluídas no pom.xml visto que esse arquivo empacotado junto com o seu artefato gerado.

Lembrando do Exercício 1, nos configurammos um mirror que usava um repositório remoto para fazer o download dos artefatos que o Maven precisa para rodar o comando dependency:tree. Imagine que esse repositório precisa de autenticação, então, configuramos no servers essa informação.

  • id

    • Representa o ID do server, seja o mirror ou repository que o irá conectar.

  • username, password

    • Nome e Senha de autenticação que deve ser usado nesse servidor.

  • privateKey, passphrase

    • Configurar a autenticação com o servidor usando uma chave privada e não mais usário e senha. Esse campos não devem ser usados em conjunto com o campo password.

  • filePermissions, directoryPermissions

    • Permissões que devem ser aplicadas nas pastas e arquivos gerados no servidor no momente de deploy de algum novo artefato. O valor aceito é um numero de 3 digitos seguindo o padrão: *nix file permissions. Pessoal do linux sabe do comando chmod 777.

Propriedade "Mirrors"
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      https://maven.apache.org/xsd/settings-1.0.0.xsd">
  ...
  <mirrors>
    <mirror>
      <id>planetmirror.com</id>
      <name>PlanetMirror Australia</name>
      <url>http://downloads.planetmirror.com/pub/maven2</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
  </mirrors>
  ...
</settings>

Um mirror seve como espelho para um ou mais determinados repositórios remoto. Imagine que você tenha uma internet bem limitada e uam quantidade muito grande de desenvolvedores, podemos configurar um repositório interno na empresa que seja um espelho do central do maven.

Com isso o o download de artefatos da WEB é feito por esse seu mirror, e o download para o repositório local do seu disco é feito pela rede interna da sua empresa usando o mirror!

  • id, name

    • Identificador único do mirror e o nome do mesmo. O id usado no mirror é usado para, caso vc tenha alguma configuração no servers, ober dados de autenticação.

  • url

    • URL que deve ser usada no lugar da original que foi espelhada.

  • mirrorOf

    • Os ids dos servidores que devem ser espelhados, ex: central,meu-outro-servidor. Caso seja * espelha qualquer um.

Para mais informações veja o link Mirror Settings

Propriedade "Proxies"
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      https://maven.apache.org/xsd/settings-1.0.0.xsd">
  ...
  <proxies>
    <proxy>
      <id>myproxy</id>
      <active>true</active>
      <protocol>http</protocol>
      <host>proxy.somewhere.com</host>
      <port>8080</port>
      <username>proxyuser</username>
      <password>somepassword</password>
      <nonProxyHosts>*.google.com|ibiblio.org</nonProxyHosts>
    </proxy>
  </proxies>
  ...
</settings>

Usado para configurar um proxy de acesso as URL usadas pelo Maven no processos de build.

  • id

    • Identificador único da configuração do proxy.

  • active

    • Valor true | false para ativar ou não o proxy.

  • protocol, host, port

    • Campos que da URL do proxy: protocol://host:port configurados separadamento!

  • username, password

    • Usuário e senha, caso o proxy precise de autenticação.

  • nonProxyHosts

    • Hosts que não devem passar pelo proxy, separador por , ou |.

Propriedade "Profiles"

Profiles são usados para customização do processo de build para determinadas situações, como por exemplo, build que deve ser executado para ambiente de desenvolvimento não precisa passar pro várias validações do que um build que é executado para entrada de produção.

Essa propriedade no settings.xml é uma versão reduzida a mesma presente no pom.xml. Composição no settins envolve apenas os elementos: activation, repositories, pluginRepositories e properties

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      https://maven.apache.org/xsd/settings-1.0.0.xsd">
  ...
  <profiles>
    <profile>
      <id>test</id>
      <activation>...</activation>
      <properties>...</properties>
      <repositories>...</repositories>
      <pluginRepositories>...</pluginRepositories>
      ...
    </profile>
  </profiles>
  ...
</settings>
  • Elemento Activation

    Elemento que indica quando esse profile deve ser ativado. Outra forma de ativação, sem ser via condicionais desse elemento é colocando a opção -P test no comandos do Maven.

    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                          https://maven.apache.org/xsd/settings-1.0.0.xsd">
      ...
      <profiles>
        <profile>
          <id>test</id>
          <activation>
            <activeByDefault>false</activeByDefault>
            <jdk>1.5</jdk>
            <os>
              <name>Windows XP</name>
              <family>Windows</family>
              <arch>x86</arch>
              <version>5.1.2600</version>
            </os>
            <property>
              <name>mavenVersion</name>
              <value>2.0.3</value>
            </property>
            <file>
              <exists>${basedir}/file2.properties</exists>
              <missing>${basedir}/file1.properties</missing>
            </file>
          </activation>
          ...
        </profile>
      </profiles>
      ...
    </settings>

    Para mais informações verificar o endereço: Profile Actiovation

  • Elemento Properties

    Elemento onde pode ser criado propriedades para serem referenciadas no processo de build, deixando assim o projeto mais customizável.

    A propriedade customizada pode ser acessada da seguinte forma no pom.xml: ${user.install}.

    No processo de build, caso eu queira mudar o valor dessa propriedades, basta adicionar a opção: -Duser-install=outro-valor.

    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                          https://maven.apache.org/xsd/settings-1.0.0.xsd">
      ...
      <profiles>
        <profile>
          ...
          <properties>
            <user.install>valor-da-minha-propriedade</user.install>
            <outra.propriedade>valor-da-minha-outra-propriedade</outra.propriedade>
          </properties>
          ...
        </profile>
      </profiles>
      ...
    </settings>

    Para mais informações virificar o endereço: Profile Properties

  • Elemento Repositories e Plugin Repositories

    Elemente onde podemos configurar os repositórios que o Maven deve usar em momento de build para obter os artefatos e popular o repositório local.

    Podemos customizar repositórios diferentes nos projfiles para determinadas condições de build.

    Ex: caso o build seja para ambiente de produção, podemos configurar repositórios no profile de produção que não aceitam o download de SNAPSHOTS (versões não finais), assim o build irá falhar caso algo passe para produção sem sua versão final.

    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                          https://maven.apache.org/xsd/settings-1.0.0.xsd">
      ...
      <profiles>
        <profile>
          ...
          <repositories>
            <repository>
              <id>codehausSnapshots</id>
              <name>Codehaus Snapshots</name>
              <releases>
                <enabled>false</enabled>
                <updatePolicy>always</updatePolicy>
                <checksumPolicy>warn</checksumPolicy>
              </releases>
              <snapshots>
                <enabled>true</enabled>
                <updatePolicy>never</updatePolicy>
                <checksumPolicy>fail</checksumPolicy>
              </snapshots>
              <url>http://snapshots.maven.codehaus.org/maven2</url>
              <layout>default</layout>
            </repository>
          </repositories>
          <pluginRepositories>
            ...
          </pluginRepositories>
          ...
        </profile>
      </profiles>
      ...
    </settings>

    Para mais informações virificar o endereço: Profile Repositories ou Profile Plugins Repositories

  • Propriedade "Active Profiles"

    Outra forma de marcar quais profiles devem ser ativados para o build do maven.

    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                          https://maven.apache.org/xsd/settings-1.0.0.xsd">
      ...
      <activeProfiles>
        <activeProfile>env-test</activeProfile>
      </activeProfiles>
    </settings>

Exercício 2

Vamos agora praticar um pouco as cofigurações settings.xml.

A pasta .m2 do home do usuário e conf da instalção do maven, não devem ter settings.xml com configurações que possam sobrepor as usadas abaixo.
A cada comando mvn dependency:tree o maven ira executar o download dos artefatos para o repositório local. Para melhor entendimento, apos a execução do comando acima, apagar o repositório local com o seguinte comando: rm -rf ~/.m2/respository ou acessando a pasta ~/.m2 e apagando manualmente.
  1. Configurar um profile com um repositório de artefatos e plugins diferente do padrão do maven.

    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                          https://maven.apache.org/xsd/settings-1.0.0.xsd">
      <profiles>
        <profile>
          <id>profile-customizado</id>
          <repositories>
            <repository>
              <id>repo-customizado</id>
              <name>Repositório de artefatos customizados</name>
              <releases>
                <enabled>true</enabled>
              </releases>
              <snapshots>
                <enabled>true</enabled>
              </snapshots>
              <url>http://element.basis.com.br/repository/public</url>
              <layout>default</layout>
            </repository>
          </repositories>
          <pluginRepositories>
            <pluginRepository>
              <id>repo-customizado</id>
              <name>Repositório de plugins customizados</name>
              <releases>
                <enabled>true</enabled>
              </releases>
              <snapshots>
                <enabled>true</enabled>
              </snapshots>
              <url>http://element.basis.com.br/repository/public</url>
              <layout>default</layout>
            </pluginRepository>
          </pluginRepositories>
        </profile>
      </profiles>
    </settings>
  2. Acessar agora a pasta treinamento_codigo_fonte e executar o build mvn dependency:tree

    O log de download deve ser semelhante ao informado abaixo:

    [INFO] Scanning for projects...
    Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-parent/2.2.1.RELEASE/spring-boot-starter-parent-2.2.1.RELEASE.pom
    Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-parent/2.2.1.RELEASE/spring-boot-starter-parent-2.2.1.RELEASE.pom (8.1 kB at 5.5 kB/s)
    Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-dependencies/2.2.1.RELEASE/spring-boot-dependencies-2.2.1.RELEASE.pom
    ...

    Veja que o profile não foi ativado, pois o maven continua realizando o downlaod dos artefatos do reposiorio padao. Vamos adicionar um condição de ativação.

    <activation>
      <activeByDefault>false</activeByDefault>
      <os>
        <name>Linux</name>
      </os>
    </activation>

    Executar o mesmo comando de build. Agora teremos a saída abaixo:

    [INFO] Scanning for projects...
    Downloading from repo-customizado: http://element.basis.com.br/repository/public/org/springframework/boot/spring-boot-starter-parent/2.2.1.RELEASE/spring-boot-starter-parent-2.2.1.RELEASE.pom
    Downloaded from repo-customizado: http://element.basis.com.br/repository/public/org/springframework/boot/spring-boot-starter-parent/2.2.1.RELEASE/spring-boot-starter-parent-2.2.1.RELEASE.pom (8.1 kB at 13 kB/s)
    Downloading from repo-customizado: http://element.basis.com.br/repository/public/org/springframework/boot/spring-boot-dependencies/2.2.1.RELEASE/spring-boot-dependencies-2.2.1.RELEASE.pom
    ...

    Quando esse projeto for executado em um ambiente Linux, ele vai usar outro repositório para fazer o downloads.

    Outra forma de ativar o profile no momento do build é com o parâmetro -P profile-customizado. Para isso, remova a configuração de activation do profile e excute o comando mvn dependency:tree -P profile-customizado para a ativação.

    E por último, podemos ativar pelo elemento activeProfiles conforme exemplo abaixo:

      <activeProfiles>
        <activeProfile>profile-customizado</activeProfile>
      </activeProfiles>

    Executando o comando mvn dependency:tree teremos o mesmo resultado dos build anteriores.

  3. Usando o settings configurado anteriormente, vamos agora adicionar um proxy:

      <proxies>
        <proxy>
          <id>meu-proxy-que-nao-existe</id>
          <active>true</active>
          <protocol>http</protocol>
          <host>proxy.somewhere.com</host>
          <port>8080</port>
          <nonProxyHosts>...</nonProxyHosts>
        </proxy>
      </proxies>

    Execute o comando maven e veja resultado:

    [INFO] Scanning for projects...
    Downloading from repo-customizado: http://element.basis.com.br/repository/public/org/springframework/boot/spring-boot-starter-parent/2.2.1.RELEASE/spring-boot-starter-parent-2.2.1.RELEASE.pom
    Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-parent/2.2.1.RELEASE/spring-boot-starter-parent-2.2.1.RELEASE.pom
    [ERROR] [ERROR] Some problems were encountered while processing the POMs:
    [FATAL] Non-resolvable parent POM for br.com.basis:treinamento-superior:0.0.1-SNAPSHOT: Could not transfer artifact org.springframework.boot:spring-boot-starter-parent:pom:2.2.1.RELEASE from/to repo-customizado (http://element.basis.com.br/repository/public): proxy.somewhere.com: Nome ou serviço desconhecido and 'parent.relativePath' points at no local POM @ line 5, column 13
    ...

    O proxy passou a ser ativo para qualuer host, como não existe apresentou erro no download dos artegatos. Como podemos resolver isso? Supondo que o proxy é para ser usado somente em Hosts que não são basis.com.br devemos configurar o nonProxyHosts: <nonProxyHosts>*.basis.com.br</nonProxyHosts>.

    [INFO] Scanning for projects...
    Downloading from repo-customizado: http://element.basis.com.br/repository/public/org/springframework/boot/spring-boot-starter-parent/2.2.1.RELEASE/spring-boot-starter-parent-2.2.1.RELEASE.pom
    Downloaded from repo-customizado: http://element.basis.com.br/repository/public/org/springframework/boot/spring-boot-starter-parent/2.2.1.RELEASE/spring-boot-starter-parent-2.2.1.RELEASE.pom (8.1 kB at 11 kB/s)
    Downloading from repo-customizado: http://element.basis.com.br/repository/public/org/springframework/boot/spring-boot-dependencies/2.2.1.RELEASE/spring-boot-dependencies-2.2.1.RELEASE.pom
    ...

    Download feito com sucesso.

  4. Vamos configurar agora o elemento servers para autenticação.

    Supondo que em uma empresa, o repsitório de artefatos do maven seja protegido com autenticação. Vamos usar o elemento servers para colocar o nosso usuário e senha.

        <servers>
            <server>
                <id>meu-servidor-interno</id>
                <username>treinamento</username>
                <password>basis123</password>
            </server>
        </servers>

    Adicionar o novo profile abaixo na sua TAG correspondete:

            <profile>
                <id>profile-interno</id>
                <repositories>
                    <repository>
                        <id>repo-interno</id>
                        <name>Repositório de artefatos interno</name>
                        <releases>
                            <enabled>true</enabled>
                        </releases>
                        <snapshots>
                            <enabled>true</enabled>
                        </snapshots>
                        <url>http://localhost:8081/repository/maven-public/</url>
                        <layout>default</layout>
                    </repository>
                </repositories>
                <pluginRepositories>
                    <pluginRepository>
                        <id>repo-interno</id>
                        <name>Repositório de plugins interno</name>
                        <releases>
                            <enabled>true</enabled>
                        </releases>
                        <snapshots>
                            <enabled>true</enabled>
                        </snapshots>
                        <url>http://localhost:8081/repository/maven-public/</url>
                        <layout>default</layout>
                    </pluginRepository>
                </pluginRepositories>
            </profile>

    e o mirror para evitar que o maven tente usar o repositório padrão central:

        <mirrors>
            <mirror>
                <id>repo-interno</id>
                <name>Miror Repositório local</name>
                <url>http://localhost:8081/repository/maven-public</url>
                <mirrorOf>central</mirrorOf>
            </mirror>
        </mirrors>

    Executar o comando mvn dependecy:tree -P profile-interno e verificar a saída do console:

    [INFO] Scanning for projects...
    Downloading from repo-interno: http://localhost:8081/repository/maven-public/org/springframework/boot/spring-boot-starter-parent/2.2.1.RELEASE/spring-boot-starter-parent-2.2.1.RELEASE.pom
    [ERROR] [ERROR] Some problems were encountered while processing the POMs:
    [FATAL] Non-resolvable parent POM for br.com.basis:treinamento-superior:0.0.1-SNAPSHOT: Could not transfer artifact org.springframework.boot:spring-boot-starter-parent:pom:2.2.1.RELEASE from/to repo-interno (http://localhost:8081/repository/maven-public/): Not authorized and 'parent.relativePath' points at no local POM @ line 5, column 13
     @
    [ERROR] The build could not read 1 project -> [Help 1]
    ...

    Repare que apresentou um erro de Not authorized no comando, ou seja, a nossa configuração de server não funcionou.

    Lembrando do que foi passado anteriormente, para as configurações de um server serem encontradas pelo seu: repository, pluginRepository ou mirror os atributo id deve ser correspondente. Nesse caso o nosso server não tem o mesmo id do repository, pluginRepository e mirror.

    O atributo ID deve ser único por repository, pluginREpository e mirror. Recomendado que toda configuração que aponter para a mesma url, no caso cima a http://localhost:8081/repository/maven-public deve possuir o mesmo id pois em teoria, estão apontando para o mesmo servidor de artefatos do maven.

    Vamos ajustar o id do server para repo-interno e executar o comando novmente.

    [INFO] Scanning for projects...
    Downloading from repo-interno: http://localhost:8081/repository/maven-public/org/springframework/boot/spring-boot-starter-parent/2.2.1.RELEASE/spring-boot-starter-parent-2.2.1.RELEASE.pom
    Downloaded from repo-interno: http://localhost:8081/repository/maven-public/org/springframework/boot/spring-boot-starter-parent/2.2.1.RELEASE/spring-boot-starter-parent-2.2.1.RELEASE.pom (8.1 kB at 6.2 kB/s)
    Downloading from repo-interno: http://localhost:8081/repository/maven-public/org/springframework/boot/spring-boot-dependencies/2.2.1.RELEASE/spring-boot-dependencies-2.2.1.RELEASE.pom
    Downloaded from repo-interno: http://localhost:8081/repository/maven-public/org/springframework/boot/spring-boot-dependencies/2.2.1.RELEASE/spring-boot-dependencies-2.2.1.RELEASE.pom (127 kB at 170 kB/s)
    ...

    Download realizado com sucesso.

    Ainda temos um grande problema, a senha do seu usuaŕio está no arquivo settings.xml e não está muito seguro, concordam? Vamos então melhorar a segurança da nossa senha.

  5. Criptorgrafia de senha dos servers configurados.

    Iniciar o processo de configuração, precisamos definir uma senha master, com o comando abaixo:

    mvn --encrypt-master-password minha-senha-master-bem-segura

    Após esse comando vai apresentar uma saída criptografa usando sua senha master. Em posse desse valor, criar o arquivo settgins-security.xml na pasta .m2 do home do seu usário: ~/.m2/settings-security.xml no caso do linux.

    <settingsSecurity>
        <master>{aydIxeQoeisHFDv8Ni0+MT/qYnYrV72bOAI6mooh/7wfXX1hEZJg4d760jNe7PSV}</master>
    </settingsSecurity>

    Com essa configuração já podem realizar a criptografia da nossa senha do servidor com o comando abaixo:

    mvn --encrypt-password basis123

    De posse da saída desse comando, vamos alterar a senha configurar no server:

            <server>
                <id>meu-servidor-interno</id>
                <username>treinamento</username>
                <password>{7A3zhkcjvqAHi7+77sg55kf4QVzsGyx5Grgas0nBqd8=}</password>
            </server>

    Executando o comando o mesmo comando de build termos a mesma saída, mais agora com a senha mais segura. Agora o arquivo settings-security.xml tem a senha master usada para criptografia dos seus passwords deixando mais segura.

    Verifique o site: Master Password em arquivo no Pendrive para verificar uma forma mais segura de manter o seu arquivo settings-security.xml.

Maven Pom.xml

O aquivo pom.xml "Projeto Object Model" é a representação em formato XML de uma projeot Maven. Toda a configuração do projeto (build, dependências, plugins, profiles, propriedades etc) que veremos mais abaixo, estão presentes nesse aquivo. É o coração do projetos Maven!

O arquivo pom.xml está presenta na raiz de um projeto Maven, com os demais arquivos do projeto.

Veja o exemplo no projeto treinamento_codigo_fonte na imagem abaixo:

background

Em destaque na imagem estão a pasta src possui todo o conteúdo do nosso projeto e o arquivo pom.xml.

Template Pom.xml

Veja no exemplo abaixo todos os principais atributos que serão detalhados abaixo. Lembrando que no momento do curso a versão, ou modelVersion desse arquivo usado é a 4.0.0.

<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>

    <!-- The Basics -->
    <groupId>...</groupId>
    <artifactId>...</artifactId>
    <version>...</version>
    <packaging>...</packaging>
    <dependencies>...</dependencies>
    <parent>...</parent>
    <dependencyManagement>...</dependencyManagement>
    <modules>...</modules>
    <properties>...</properties>

    <!-- Build Settings -->
    <build>...</build>
    <reporting>...</reporting>

    <!-- More Project Information -->
    <name>...</name>
    <description>...</description>
    <url>...</url>
    <inceptionYear>...</inceptionYear>
    <licenses>...</licenses>
    <organization>...</organization>
    <developers>...</developers>
    <contributors>...</contributors>

    <!-- Environment Settings -->
    <issueManagement>...</issueManagement>
    <ciManagement>...</ciManagement>
    <mailingLists>...</mailingLists>
    <scm>...</scm>
    <prerequisites>...</prerequisites>
    <repositories>...</repositories>
    <pluginRepositories>...</pluginRepositories>
    <distributionManagement>...</distributionManagement>
    <profiles>...</profiles>
</project>

Para os detalhes completos de cada atributo do arquivo pom.xml verificar o link Maven project descriptor

Vamos abordar no curso as propriedades mais relevantes, algumas já foram abordadas no settings.xml e tem o mesmo comportamento e atributos quando usadas no pom.xml. Vamos começar!

Propriedades "Maven Coordinates"

O mínimo que um arquivo pom.xml precisa para o funcionamento está descrito abaixo:

<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>org.codehaus.mojo</groupId>
  <artifactId>my-project</artifactId>
  <version>1.0</version>
</project>
  • modelVersion

    • Indica a versão do pom.xml usada para criar esse arquivo. Vamos ver somente essa no curso.

  • groupId, artifactId e version

    • Essas propriedades juntas correspondem ao que chamamos de Maven Coordinates que é usado pelo maven para localizar o seu artefato, seja no repositório local ou repositório remoto quando for realizar o download.

      • groupId

        • Normalmente define a sua Organização ou um Projeto: br.com.basis

      • artifactId

        • Normamente é usado para definir o nome do projeto ou parte do do projeto: treinamento

      • version

        • É usada para obter obter uma versão do projeto: 1.0.0. Esse valor é normamente incrementado quando novas releaes do seu projeto foram liberadas. Imagine como uma versão, uma TAG em um repositório de versionamento de código.

Propriedades "packaging"
<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">
  ...
  <packaging>war</packaging>
  ...
</project>

Essa propriedade define o que é o seu artefato. No desenvolvimento Java muito comum os artefatos terem a extensão: jar, war e ear. Esses são alguns exemploes do valor dessa propriedades.

Esse valor não é obrigatório e caso não seja informado seu valor será o padrão jar. Os valores aceitos são: pom, jar, maven-plugin, ejb, war, ear, rar. Esses valores influenciam no ciclo de vida do build do Maven, um porjeto de packaging do tipo war tem um build e plugins ativados diferente de um projeto do tipo jar.

Não confundam o valor dessa propriedade com a extensão do arquivo gerado no processo de build, como exemplo, um projeto com packaging do tipo ejb no final do build tem um arquivo com a extensão jar gerado.

Propriedades "Dependencies"
<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
                      https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <type>jar</type>
      <scope>test</scope>
      <optional>true</optional>
      <classifier></classifier>
    </dependency>
    ...
  </dependencies>
  ...
</project>

Essa propriedade é uma das propriedades que fazem a ligação entre projetos Maven, as outras formas são via herança e agragação, veremos mais no decorrer do curso.

Com essa propriedade que iremos configurar, quais artefatos são necessários para o nosso projeto Maven, seja para compilação, testes ou execução final de forma correta e simples. Quem nunca ficou procurando na internet um jar ou um zip cheio de jars para colocar manualmente na IDE para compilação e execução do projeto.

  • groupId, artifactId, version

    • Conforme falado anteriormente define as coordenadas do seu projeto para que o Maven localize e realize a configuração correta no momente de build do projeto.

      • version

        • No caso de uma dependência o Maven permite espeficiar um intervalo e não somente uma versão específica. Vamos supor que você deseja usar a versão 4.0 do Hibernate mais não quer ficar parado no tempo caso uma correção seja lançada para essa versão. Você pode especificar da seguinte maneira: <version>[4.0,5.0)</version>. Nesse caso você vai usar a útlima versão 4.0 lançada até o limite da 5.0. Para mais informações acesso o link: Dependency Version Requirement Specification

  • classifier

    • Essa propriedade serve para classificar o artefato gerado pelo build do Maven de um mesmo projeto, mais que pode ter o seu conteṹdo alterado. Exemplo seria a geração e uma dependência que possa ser executar com Java 1.4, 1.5, 1.6. Caso você compile seu fonte e gere a dependência com Java 1.6 a mesma não será compatível com vesão anterior. Nesse caso o desenvolvedor vai gerar do mesmo projeto 3 versões. A padrão com 1.6 e as demais com um classificador, por exemplo, jdk5 e jdk4. Assim o maven sabe que deve obter da memas coordenada, um artefato específico para Jdk5 e não o padrão.

  • type

    • A exemplo do packaging define qual o tipo da dependência. Na maioria dos casos, o tipo será jar que é o valor padrão.

  • scope

    • Define qual em qual escopo a dependência deve ser usada e também limita se a mesma deve ser transitiva ou não para quem usar o seu projeto como dependência.

      • compile

        • Escopo padrão de uma dependência. A mesma será usada no processo de complicação, execução e testes do seu artefato e também é usada como dependência transitiva.

      • provided e system

        • Escopos parecido com o compile onde o Maven espera que no processo de execução a dependência esteja presente e não é usada como transitiva. Diferença em usar system é que você deve fornecer o caminho completo de onde está o arquivo que o maven deve usar com a propriedade systemPath, ou seja, o Maven não vai consultar os respositíros locais e remotos especificados para o projeto vai buscar do caminho informado no systemPath. systemPath é esclusivo para o escopo system.

  • optional

    • Define que essa dependência é opicional para o funcionamento correto do sistema. Vamos supor que a dependência usada no seu projeto é apra atender uma situação muito específica que não vai ser usada somente em 1% dos casos onde seu projeto for adicionado como dependência, podemos marcar como opicional nesse caso.

Ainda na propriedade dependency temos uma forma de excluir dependências transitivas usando a propriedade exclusions abaixo:

<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
                      https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <dependencies>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-embedder</artifactId>
      <version>2.0</version>
      <exclusions>
        <exclusion>
          <groupId>org.apache.maven</groupId>
          <artifactId>maven-core</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    ...
  </dependencies>
  ...
</project>

Ainda podemos configurar uma forma de excluir tudo, usando o wildcard *. Podemos configurar da seguinte forma:

<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
                      https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <dependencies>
    <dependency>
      <groupId>org.minha.organizacao</groupId>
      <artifactId>minha-dependência-1</artifactId>
      <version>2.0</version>
      <exclusions>
        <exclusion> (1)
          <groupId>*</groupId>
          <artifactId>*</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.minha.organizacao</groupId>
      <artifactId>minha-dependência-2</artifactId>
      <version>2.0</version>
      <exclusions>
        <exclusion> (2)
          <groupId>*</groupId>
          <artifactId>maven-core</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.minha.organizacao</groupId>
      <artifactId>minha-dependência-3</artifactId>
      <version>2.0</version>
      <exclusions>
        <exclusion> (3)
          <groupId>org.apache.maven</groupId>
          <artifactId>*</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    ...
  </dependencies>
  ...
</project>
1 Excluir todas as dependências transitivas.
2 Excluir todas os artefatos chamados mavem-core independente do groupId.
3 Excluir todas os artefatos do grupo org.apache.maven independente do artifactId.
Exercício 1

Vamos praticar um pouco agora.

Nesse ponto, configurar o settings.xml na pasta ~/.m2 de forma padrão para que seja possível executar o build e comunicar corretamente com o repositório padrão do Maven.
  1. Criar 3 projetos maven simples com as configurações mínimas conforme visto acima.

    <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>br.com.treinamento</groupId>
      <artifactId>nome-seu-projeto</artifactId>
      <version>1.0.0</version>
    </project>
    • Vamos organizar na estrutura:

      • projeto-ex01

        • Projeto 01 dentro da pasta projeto-ex01 do tipo jar

      • projeto-ex02

        • Projeto 02 dentro da pasta projeto-ex02 do tipo jar

      • projeto-ex03

        • Projeto 03 dentro da pasta projeto-ex03 do tipo war

    O resultado final da configuração deve ser conforme listado abaixo na imagem:

    background

    Cada pasta vai possui apenas o arquivo pom.xml com a configuração mínima para um projeto Maven funcionar corretamente.

  2. Executar o comando de empacotaemnto do Maven.

    • Acessar a pasta do projeto-ex01 e executar o comando abaixo para compilar e gerar o pacote do nosso projeto.

    mvn package

    O resultado esperado será conforma abaixo:

    [INFO] Scanning for projects...
    [INFO]
    [INFO] ------------------< br.com.treinamento:projeto-ex01 >------------------- (1)
    [INFO] Building projeto-ex01 1.0.0
    [INFO] --------------------------------[ jar ]--------------------------------- (2)
    [INFO]
    [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ projeto-ex01 ---
    [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
    [INFO] skip non existing resourceDirectory /home/felipe/Ambiente/treinamento/exercicio01/projeto-ex01/src/main/resources
    [INFO]
    [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ projeto-ex01 ---
    [INFO] No sources to compile
    [INFO]
    [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ projeto-ex01 ---
    [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
    [INFO] skip non existing resourceDirectory /home/felipe/Ambiente/treinamento/exercicio01/projeto-ex01/src/test/resources
    [INFO]
    [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ projeto-ex01 ---
    [INFO] No sources to compile
    [INFO]
    [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ projeto-ex01 ---
    [INFO] No tests to run.
    [INFO]
    [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ projeto-ex01 ---
    [WARNING] JAR will be empty - no content was marked for inclusion!
    [INFO] Building jar: /home/felipe/Ambiente/treinamento/exercicio01/projeto-ex01/target/projeto-ex01-1.0.0.jar
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS (3)
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  1.387 s
    [INFO] Finished at: 2020-02-06T21:01:26-03:00
    [INFO] ------------------------------------------------------------------------
    1 Informação de groupId:artifactId definidas no nosso projeto.
    2 Tipo de empacotamento do nosso projeto.
    3 Resultado final do BUILD.

    Repetir o comando para os projetos projeto-ex02 e projeto-ex03 e verificar o resultado.

  3. Ajustar configuração do projeto-ex03.

    Neste ponto você deve ter percebido que o projeto-ex03 não executou corretamente, para corrigir esse problema neste momento vamos configurar para ignorar a falta do arquivo web.xml pois não é o foco neste momento.Propriedades "Dependencies"

    • Acessar editar o arquivo pom.xml com a configuração abaixo:

    <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>br.com.treinamento</groupId>
      <artifactId>projeto-ex03</artifactId>
      <version>1.0.0</version>
      <packaging>war</packaging>
    
      <build> (1)
        <plugins>
          <plugin> (2)
            <artifactId>maven-war-plugin</artifactId>
            <version>3.1.0</version>
            <configuration>
             <failOnMissingWebXml>false</failOnMissingWebXml> (3)
            </configuration>
          </plugin>
        </plugins>
      </build>
    
    </project>
    1 Tag que permite a configuração do build do projeto
    2 Tag que permite a configuração de plugins para o projeto
    3 Configuração do plugin maven-war-plugin para ignorar a falta do arquivo web.xml

    Executar novamente o build e verificar o resultado de sucesso!

    Vários outros logs accima ...
    
    [INFO]
    [INFO] --- maven-war-plugin:3.1.0:war (default-war) @ projeto-ex03 --- (1)
    [INFO] Packaging webapp
    [INFO] Assembling webapp [projeto-ex03] in [/home/felipe/Ambiente/treinamento/exercicio01/projeto-ex03/target/projeto-ex03-1.0.0]
    [INFO] Processing war project
    [INFO] Webapp assembled in [13 msecs]
    [INFO] Building war: /home/felipe/Ambiente/treinamento/exercicio01/projeto-ex03/target/projeto-ex03-1.0.0.war
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS (2)
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  1.739 s
    [INFO] Finished at: 2020-02-06T21:04:02-03:00
    [INFO] ------------------------------------------------------------------------
    1 Indicando que o plugin configurado foi ativado no build
    2 Resultado de sucesso do build.
  4. Adicionando dependência entre os projetos.

    • Adicionar como dependência no pom.xml do projeto-ex02 o projeto-ex01 e executar o comando de empacotamento do maven.

    [INFO] Scanning for projects...
    [INFO]
    [INFO] ------------------< br.com.treinamento:projeto-ex02 >-------------------
    [INFO] Building projeto-ex02 1.0.0
    [INFO] --------------------------------[ jar ]---------------------------------
    Downloading from central: https://repo.maven.apache.org/maven2/br/com/treinamento/projeto-ex01/1.0.0/projeto-ex01-1.0.0.pom
    [WARNING] The POM for br.com.treinamento:projeto-ex01:jar:1.0.0 is missing, no dependency information available (1)
    Downloading from central: https://repo.maven.apache.org/maven2/br/com/treinamento/projeto-ex01/1.0.0/projeto-ex01-1.0.0.jar
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD FAILURE (2)
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  2.553 s
    [INFO] Finished at: 2020-02-06T21:14:08-03:00
    [INFO] ------------------------------------------------------------------------
    [ERROR] Failed to execute goal on project projeto-ex02: Could not resolve dependencies for project br.com.treinamento:projeto-ex02:jar:1.0.0: Could not find artifact br.com.treinamento:projeto-ex01:jar:1.0.0 in central (https://repo.maven.apache.org/maven2) -> [Help 1] (3)
    [ERROR]
    [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
    [ERROR] Re-run Maven using the -X switch to enable full debug logging.
    [ERROR]
    [ERROR] For more information about the errors and possible solutions, please read the following articles:
    [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/DependencyResolutionException
    1 Indicando um possível problema de falta de dependência.
    2 Indicador de Falha no Build.
    3 Informação do problema do build, falta da dependência.

    Ao executar o comando para gerar o artefado do projeto-ex02 o Maven verifica que é necessário obter o artefato do projeto-ex01 para continuar com o processo de build. Como o ele não encontra no repositório de artefatos remoto o build falha.

    Como já visto o Mavem tem um repositório local de artefatos pra fazer o cache e não baixar sempre que um comando de build for executado. Vamos colocar nosso projeto-ex01 nesse repositório local para resolver o problema.

    • Gerar o artefato do projeto-ex01 no repositório local.

    Executar o comando de instalção local para resolver o problema.

    felipe@felipe-Inspiron-5421:~/Ambiente/treinamento/exercicio01/projeto-ex01$ mvn install
    
    Varios outros logs acima ...
    
    [INFO]
    [INFO] --- maven-install-plugin:2.4:install (default-install) @ projeto-ex01 --- (1)
    [INFO] Installing /home/felipe/Ambiente/treinamento/exercicio01/projeto-ex01/target/projeto-ex01-1.0.0.jar to /home/felipe/Ambiente/maven/repositorio-local/br/com/treinamento/projeto-ex01/1.0.0/projeto-ex01-1.0.0.jar (2)
    [INFO] Installing /home/felipe/Ambiente/treinamento/exercicio01/projeto-ex01/pom.xml to /home/felipe/Ambiente/maven/repositorio-local/br/com/treinamento/projeto-ex01/1.0.0/projeto-ex01-1.0.0.pom  (3)
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  1.309 s
    [INFO] Finished at: 2020-02-06T21:21:03-03:00
    [INFO] ------------------------------------------------------------------------
    1 Indicando que o plugin de instação foi executado.
    2 Informação de onde foi gerado e copiado o artefato jar do projeto-ex01
    3 Informação de onde foi gerado e copiado o pom.xml do projeto-ex01

    Agora repetir o comando de empacotamento no projeto-ex02 e verificar o resultado.

    Varios outros logs acima ...
    
    [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ projeto-ex02 ---
    [WARNING] JAR will be empty - no content was marked for inclusion!
    [INFO] Building jar: /home/felipe/Ambiente/treinamento/exercicio01/projeto-ex02/target/projeto-ex02-1.0.0.jar
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  1.285 s
    [INFO] Finished at: 2020-02-06T21:24:00-03:00
    [INFO] ------------------------------------------------------------------------

    Veja que temos o resultado de sucesso.

  5. Adicionar dependência ao projeto-ex03

    • Adicionar como dependência no projeto-ex03 o projeto-ex02

    • Executar o comando de empacotamento no projeto-ex03

    • Verificar a pasta projeto-ex03/target/projeto-ex03-1.0.0/WEB-INF/libs e veja os 2 artefatos copiados lá.

    felipe@felipe-Inspiron-5421:~/Ambiente/treinamento/exercicio01/projeto-ex03/target/projeto-ex03-1.0.0/WEB-INF/lib$ ls
    projeto-ex01-1.0.0.jar  projeto-ex02-1.0.0.jar
  6. Configurar exclusão de dependência transitiva no projeto-ex03

    • Adicionar um exclusion para o projeto-ex01 na dependência projeto-ex02

        <dependency>
          <groupId>br.com.treinamento</groupId>
          <artifactId>projeto-ex02</artifactId>
          <version>1.0.0</version>
          <exclusions>
            <exclusion>
              <groupId>br.com.treinamento</groupId>
              <artifactId>projeto-ex01</artifactId>
            </exclusion>
          </exclusions>
        </dependency>
    • Executar o comando de empacotamento no projeto-ex03 mais antes apagar a pasta target com o comando mvn clean

    • Verificar a pasta projeto-ex03/target/projeto-ex03-1.0.0/WEB-INF/libs devemos ter somtente 1 artefato agora.

    felipe@felipe-Inspiron-5421:~/Ambiente/treinamento/exercicio01/projeto-ex03/target/projeto-ex03-1.0.0/WEB-INF/lib$ ls
    projeto-ex02-1.0.0.jar

    Este é o básico de adicionar dependências em um projeto.

Propriedades "Dependency Management"

A configuração de Dependency Management no Maven está ligado, principamente, ao conceito de Inheritance (herança) onde é mais usado.

Temos um projeto muito grande, dividido em várias módulos como: libs, microserviços, processadores Batch e etc. Precisamos que isso tudo seja configurado de uma maneira comum e tenham as mesmas versões de certos bibliotecas java, por exemplo, jasperReports, Spring SEcurity e etc.

Aplicando o conceito de herança juntamente com o gerenciamento dependência, conseguimos criar uma configuração bem mais simples e compartilhada.

Basicamente a configuração Dependency Management serve para definir uma dependência em uma versão específica que dever ser usada em modulos desse projeto.

<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
                      https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>br.com.minha-empresa</groupId>
  <artifactId>meu-projeto-parent</artifactId>
  <version>2.0</version>
  <packaging>pom</packaging>

  ...

  <dependencyManagement> (1)
    <dependencies>
      <dependency>
        <groupId>br.com.outra-empresa</groupId>  (2)
        <artifactId>outro-projeto</artifactId>  (2)
        <version>1.0.0</version> (3)
      </dependency>
    </dependencies>
  </dependencyManagement>

  ...

</project>
1 Tag para configuração do gerenciamento.
2 A dependência gerenciada.
3 A Versão gerenciada.

Com essa configuração nos podemos agora configurar um módulo dessa aplicação para usar essa dependência de uma forma mais simples e compartilhada.

<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
                      https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent> (1)
    <groupId>br.com.minha-empresa</groupId>
    <artifactId>meu-projeto-parent</artifactId>
    <version>2.0</version>
  </parent>

  <artifactId>meu-modulo-do-projeto</artifactId>
  <version>2.5</version>

  <dependencies>
    <dependency> (2)
      <groupId>br.com.outra-empresa</groupId>
      <artifactId>outro-projeto</artifactId>
    </dependency>
  </dependencies>

</project>
1 Tag para configuração da herança para usar o gerenciamento de dependência.
2 Dependência adicionado no módulo e com a versão gerenciada pelo Parent

O que não se pode confundir é que Dependency Management não indica que estamos usando a dependência realmente, indica apenas que, quando for usada, não precisamos informar a tag version pois ela é gerenciada ou se a dependencia estiver presente como transitiva, a versão que será usada é a que colocamos como gerenciada. Caso a tag version seja informada com outro valor este vai sobrepor o que está geranciado no parent.

Outro ponto importante, não é obrigatório usar o Dependency Management somente usando o conceito de herança. Isso também pode ser aplicado nos projetos jar, war e etc no mesmo pom.xml, mas o seu uso maior será juntamento com conceito de herança.

Propriedade "Build"

A Propriedade build no pom.xml pode ser encontrado em 2 pontos, onde chamamos de Project Build e Profile Build veja abaixo:

<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
                      https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <build>...</build> (1)

  <profiles>
    <profile>
      <build>...</build> (2)
    </profile>
  </profiles>

</project>
1 Project Build.
2 Profile Build.

São esses os dois pontos onde conseguimos customizar o processo de build do nosso projeto maven.

Vamos detalhar suas configurações.

BaseBuild Elements e Build Element Set

Na tag build temos os seguintes elementos mais simples:

<build>
  <defaultGoal>install</defaultGoal> (1)
  <directory>${basedir}/target</directory> (2)
  <finalName>${artifactId}-${version}</finalName> (3)
  <filters> (4)
    <filter>filters/filter1.properties</filter>
  </filters>
  <sourceDirectory>${basedir}/src/main/java</sourceDirectory> (5)
  <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory> (6)
  <outputDirectory>${basedir}/target/classes</outputDirectory> (7)
  <testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory> (8)
  ...
</build>
1 Elemento é usado para definir o comando maven padrão quando nenhum comando for executado.
2 Diretório usado pelo processo de build para geração dos arquivos.
3 Nome final do artefato gerado por esse build, ex: apache-commons-1.3.4.jar. A extensão .jar não faz parte do nome final, ela é colocada pelo plugin maven-jar-plugin. Plugins podem alterar ou ignorar essa configuração.
4 Filtros são arquivos .properties com os pares chave=valor usados para customizar os valores com onde estão entre ${chave}.
5 Confguração da pasta onde estão os fontes do projeto, no caso os arquivos .java. (Presente apenas no Project build do projeto)
6 Confguração da pasta onde estão os fontes do projeto responsáveis na execução de testes, no caso os arquivos .java. (Presente apenas no Project build do projeto)
7 Pasta onde será gerado os arquivos compilados, no caso os .class relacionado a pasta sourceDirectory. (Presente apenas no Project build do projeto)
8 Pasta onde será gerado os arquivos compilados, no caso os .class relacionado a pasta testOutputDirectory. (Presente apenas no Project build do projeto)

Na maioria dos projetos esses caminhos não são alterados e seguem com seus valores padrão, mas é bom saber disso caso você tenha que migrar um projeto não Maven onde manter a estrutura de pastas é obrigatório.

Elemento Resources e TestResources

Este elemento está presente no Projeto Build e Profile Build e tem como objetivo configurar arquivos de recurso para aplicação. Arquivos de recuros não são códigos fontes, não são compilados e podem ou não passar pro processo de filtro para serem incluídos no artefato final gerado pelo build do Maven.

Existem e pastas de recurso default nos projeto Mavem:

  • <directory>${basedir}/src/main/resources</directory>

    • Escopo main do projeto

  • <directory>${basedir}/src/test/resources</directory>

    • Escopo test do projeto

<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
                      https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <build>
    ...
    <resources>
      <resource> (1)
        <targetPath>META-INF/plexus</targetPath> (2)
        <filtering>false</filtering> (3)
        <directory>${basedir}/src/main/plexus</directory> (4)
        <includes> (5)
          <include>configuration.xml</include>
        </includes>
        <excludes> (6)
          <exclude>**/*.properties</exclude>
        </excludes>
      </resource>
    </resources>
    <testResources> (7)
      ...
    </testResources>
    ...
  </build>
</project>
1 Cada TAG define um diretório de recurso.
2 Caminho relativo de onde esses recursos serão colocados no artefato final gerado, ex, .jar
3 Indica se esses recursos devem passar por um processo de filtro antes de serem adicionados ao artefato.
4 Diretório onde os recursos serão encontrados para processo de Build.
5 Nomes dos recursos que devem ser incluídos
6 Nomes dos recursos que devem ser excluídos. Caso o mesmo recurso apareça no filtro de incluir e excluir, vale o excluir.
7 Tem as mesmas propriedades do resource mas nesse ponto usamos a tag testResouce.
Elemento Plugins

Este elemento está presente no Projeto Build e Profile Build e tem como objetivo configurar os plugins do maven que serão usados no processo de build. Podemos nesse ponto, configurar o plugin maven-jar-plugin para usar JDK 1.8 pra compilação.

<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
                      https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <build>
    ...
    <plugins>
      <plugin> (1)
        <groupId>org.apache.maven.plugins</groupId>  (2)
        <artifactId>maven-jar-plugin</artifactId> (2)
        <version>2.6</version> (2)
        <extensions>false</extensions> (3)
        <inherited>true</inherited> (4)
        <configuration> (5)
          <classifier>test</classifier>
        </configuration>
        <dependencies>...</dependencies> (6)
        <executions>...</executions> (7)
      </plugin>
    </plugins>
  </build>
</project>
1 Cada TAG define um plugin
2 Informação de qual plugin está sendo usado e sua versão.
3 Informar se deseja ativas ou não as extensions desse plugin.
4 Informar se esse plugin deve ser herdado pelos projetos filhos.
5 Configurações gerais do plugin que serão aplicadas a todas as executions
6 Mesmo que a dependencia do pom.xml mais somente no escopo de execução do plugin.
7 Todas as execuções que esse plugin irá realizar no processo de build.

Quando adicionamos um plugin no pom.xml nos precisamos configurar as execuções dele no processo de build. Alguns plugins já tem execuções configuradas devido ao tipo de projeto que estamos criando.

Abaixo detalhamos mais sobre as configuraçoes de execução do plugin.

<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
                      https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.1</version>
        <executions>
          <execution> (1)
            <id>echodir</id> (2)
            <goals> (3)
              <goal>run</goal>
            </goals>
            <phase>verify</phase> (4)
            <inherited>false</inherited> (5)
            <configuration> (6)
              <tasks>
                <echo>Build Dir: ${project.build.directory}</echo>
              </tasks>
            </configuration>
          </execution>
        </executions>

      </plugin>
    </plugins>
  </build>
</project>
1 Cada TAG define uma execução do plugin
2 Identificador da execução que será exibido no processo de build.
3 Lista de tarefas goal que serão chamado para o plugin em questão.
4 Indica em qual momento no ciclo de vida do build essa execução deve ocorrer
5 Indicar se esta execução deve ser herdada pelos projetos filhos.
6 Configurações específicas do plugin para essa execução em questão.

Com essas configurações de plugins que conseguimos realizar a customização do nosso processo de build e assim gerar o artefato final conforme a necessidade.

Elemento Plugin Management

Este elemento tem os mesmas informações do elemento Plugin, e se comporta igual ao Dependency Management. Usado para compartilhar as configurações de plugins entre os projetos filhos.

<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
                      https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <build>
    ...
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-jar-plugin</artifactId>
          <version>2.6</version>
          <extensions>false</extensions>
          <inherited>true</inherited>
          <configuration>
            <classifier>test</classifier>
          </configuration>
          <dependencies>...</dependencies>
          <executions>...</executions>
            <execution>
              <id>pre-process-classes</id>
              <phase>compile</phase>
              <goals>
                <goal>jar</goal>
              </goals>
              <configuration>
                <classifier>pre-process</classifier>
              </configuration>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>
    ...
  </build>
</project>

Com está confguração basta que no projeto filho eu coloque apenas a declaração do plguin, mesmo sem o a versão:

<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
                      https://maven.apache.org/xsd/maven-4.0.0.xsd">

  <parent> (1)
    <groupId>br.com.minha-empresa</groupId>
    <artifactId>meu-projeto-parent</artifactId>
    <version>2.0</version>
  </parent>

  ...
  <build>
    ...
      <plugins>
        <plugin> (2)
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-jar-plugin</artifactId>
        </plugin>
      </plugins>
    ...
  </build>
</project>
1 Informação do projeto parent com a configuração do plugin.
2 Apenas declaro o plugin e todas suas configurações são herdadas do parent.

Para informações de todas as configuraçoes presentes no pom.xml acesse o site: POM Reference nele todos as informações estão detalhas. Aqui temos apenas as mais importantes para o processo de build e o treinamento.

Exercício 2

Vamos praticar um pouco agora.

Nesse ponto, configurar o settings.xml na pasta ~/.m2 de forma padrão para que seja possível executar o build e comunicar corretamente com o repositório padrão do Maven.
  1. Vamos criar 1 projeto maven simples para iniciarmos as configurações

    • Criar uma pasta com nome projeto-config

    • Criar arquivo pom.xml básico do projeto

    <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>br.com.treinamento</groupId>
      <artifactId>nome-seu-projeto-config</artifactId>
      <version>1.0.0</version>
    </project>
    • Executar o comando maven abaixo para verificarmos como está configurado o pom.xml no final do build

    mvn help:help:effective-pom

    Dentre os vários logs no console o maven vai imprimir um conteúdo de um arquivo pom.xml igual abaixo:

    As tags estão fechadas para melhor entendimento.
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- ====================================================================== -->
    <!--                                                                        -->
    <!-- Generated by Maven Help Plugin on 2020-03-06T19:58:37-03:00            -->
    <!-- See: http://maven.apache.org/plugins/maven-help-plugin/                -->
    <!--                                                                        -->
    <!-- ====================================================================== -->
    <!-- ====================================================================== -->
    <!--                                                                        -->
    <!-- Effective POM for project                                              -->
    <!-- 'br.com.treinamento:nome-seu-projeto-config:jar:1.0.0'                 -->
    <!--                                                                        -->
    <!-- ====================================================================== -->
    <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>br.com.treinamento</groupId>
      <artifactId>nome-seu-projeto-config</artifactId>
      <version>1.0.0</version>
      <repositories>
        <repository>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
          <id>central</id>
          <name>Central Repository</name>
          <url>https://repo.maven.apache.org/maven2</url>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <releases>
            <updatePolicy>never</updatePolicy>
          </releases>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
          <id>central</id>
          <name>Central Repository</name>
          <url>https://repo.maven.apache.org/maven2</url>
        </pluginRepository>
      </pluginRepositories>
      <build>
        <sourceDirectory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/src/main/java</sourceDirectory>
        <scriptSourceDirectory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/src/main/scripts</scriptSourceDirectory>
        <testSourceDirectory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/src/test/java</testSourceDirectory>
        <outputDirectory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/target/classes</outputDirectory>
        <testOutputDirectory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/target/test-classes</testOutputDirectory>
        <resources>
          <resource>
            <directory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/src/main/resources</directory>
          </resource>
        </resources>
        <testResources>
          <testResource>
            <directory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/src/test/resources</directory>
          </testResource>
        </testResources>
        <directory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/target</directory>
        <finalName>nome-seu-projeto-config-1.0.0</finalName>
        <pluginManagement>
          <plugins>
            <plugin>
              <artifactId>maven-antrun-plugin</artifactId>
              <version>1.3</version>
            </plugin>
            <plugin>
              <artifactId>maven-assembly-plugin</artifactId>
              <version>2.2-beta-5</version>
            </plugin>
            <plugin>
              <artifactId>maven-dependency-plugin</artifactId>
              <version>2.8</version>
            </plugin>
            <plugin>
              <artifactId>maven-release-plugin</artifactId>
              <version>2.5.3</version>
            </plugin>
          </plugins>
        </pluginManagement>
        <plugins>
          <plugin>
            <artifactId>maven-clean-plugin</artifactId>
            <version>2.5</version>
            <executions>
              <execution>
                <id>default-clean</id>
                <phase>clean</phase>
                <goals>
                  <goal>clean</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.6</version>
            <executions>
              <execution>
                <id>default-testResources</id>
                <phase>process-test-resources</phase>
                <goals>
                  <goal>testResources</goal>
                </goals>
              </execution>
              <execution>
                <id>default-resources</id>
                <phase>process-resources</phase>
                <goals>
                  <goal>resources</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <executions>
              <execution>
                <id>default-jar</id>
                <phase>package</phase>
                <goals>
                  <goal>jar</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <executions>
              <execution>
                <id>default-compile</id>
                <phase>compile</phase>
                <goals>
                  <goal>compile</goal>
                </goals>
              </execution>
              <execution>
                <id>default-testCompile</id>
                <phase>test-compile</phase>
                <goals>
                  <goal>testCompile</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.12.4</version>
            <executions>
              <execution>
                <id>default-test</id>
                <phase>test</phase>
                <goals>
                  <goal>test</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <artifactId>maven-install-plugin</artifactId>
            <version>2.4</version>
            <executions>
              <execution>
                <id>default-install</id>
                <phase>install</phase>
                <goals>
                  <goal>install</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <artifactId>maven-deploy-plugin</artifactId>
            <version>2.7</version>
            <executions>
              <execution>
                <id>default-deploy</id>
                <phase>deploy</phase>
                <goals>
                  <goal>deploy</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <artifactId>maven-site-plugin</artifactId>
            <version>3.3</version>
            <executions>
              <execution>
                <id>default-site</id>
                <phase>site</phase>
                <goals>
                  <goal>site</goal>
                </goals>
                <configuration>
                  <outputDirectory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/target/site</outputDirectory>
                  <reportPlugins>
                    <reportPlugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-project-info-reports-plugin</artifactId>
                    </reportPlugin>
                  </reportPlugins>
                </configuration>
              </execution>
              <execution>
                <id>default-deploy</id>
                <phase>site-deploy</phase>
                <goals>
                  <goal>deploy</goal>
                </goals>
                <configuration>
                  <outputDirectory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/target/site</outputDirectory>
                  <reportPlugins>
                    <reportPlugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-project-info-reports-plugin</artifactId>
                    </reportPlugin>
                  </reportPlugins>
                </configuration>
              </execution>
            </executions>
            <configuration>
              <outputDirectory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/target/site</outputDirectory>
              <reportPlugins>
                <reportPlugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-project-info-reports-plugin</artifactId>
                </reportPlugin>
              </reportPlugins>
            </configuration>
          </plugin>
        </plugins>
      </build>
      <reporting>
        <outputDirectory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/target/site</outputDirectory>
      </reporting>
    </project>
    

    Você pode observar que muito das configurações não estão no seu pom.xml padrão, mas é assim que o maven interpreta o seu arquivo, quando for executar algum dos seus goals, como por exemplo, clean verify.

    • Vamo mudar as configuraçoes dos caminhos dos diretórios de Source e Test.

    <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>br.com.treinamento</groupId>
      <artifactId>nome-seu-projeto-config</artifactId>
      <version>1.0.0</version>
    
      <build>
        <sourceDirectory>pasta/fontes</sourceDirectory>
        <testSourceDirectory>pasta/testes</testSourceDirectory>
      </build>
    </project>

    Ao executar o comando maven agora temos na saída nova nova pasta configurada:

    <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>br.com.treinamento</groupId>
      <artifactId>nome-seu-projeto-config</artifactId>
      <version>1.0.0</version>
      ...
      <build>
        <sourceDirectory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/pasta/fontes</sourceDirectory> (1)
        <scriptSourceDirectory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/src/main/scripts</scriptSourceDirectory>
        <testSourceDirectory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/pasta/testes</testSourceDirectory> (2)
        ...
      </build>
    </project>
    1 Novo caminho Source
    2 Novo caminho Teste
    • Vamos agora configurar a versão de compilação do nosso projeto no plugin maven-compile-plugin. Adicionar a configuração abaixo no pom.

        <plugins>
          <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
              <target>1.8</target>
              <source>1.8</source>
            </configuration>
          </plugin>
        </plugins>

    Executar o comando para verificar o resultado. Comparando agora com o pom.xml antigo, podemos ver que o plugin de compilção foi alterado com a nossa nova configuração e ela foi copiada para as execuções padrão deste plugin.

    <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>br.com.treinamento</groupId>
      <artifactId>nome-seu-projeto-config</artifactId>
      <version>1.0.0</version>
      ...
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <executions>
              <execution>
                <id>default-compile</id>
                <phase>compile</phase>
                <goals>
                  <goal>compile</goal>
                </goals>
                <configuration> (2)
                  <target>1.8</target>
                  <source>1.8</source>
                </configuration>
              </execution>
              <execution>
                <id>default-testCompile</id>
                <phase>test-compile</phase>
                <goals>
                  <goal>testCompile</goal>
                </goals>
                <configuration> (2)
                  <target>1.8</target>
                  <source>1.8</source>
                </configuration>
              </execution>
            </executions>
            <configuration> (1)
              <target>1.8</target>
              <source>1.8</source>
            </configuration>
          </plugin>
          ...
        </plugins>
        ...
      </build>
    </project>
    1 Nossa configuração
    2 Configuração copiada para as execuções padrão de compilação.
    • Agora vamos configurar também novos caminhos de resource e testResource para o projeto

        <resources>
          <resource>
            <directory>pasta/recursos</directory>
            <filtering>true</filtering>
            <includes>
              <include>arquivos.properties</include>
            </includes>
          </resource>
          <resource>
            <directory>pasta/recursos</directory>
            <filtering>false</filtering>
            <includes>
              <include>estaticos.properties</include>
            </includes>
          </resource>
        </resources>
        <testResources>
          <testResource>
            <directory>pasta/recursos-teste</directory>
            <filtering>true</filtering>
            <includes>
              <include>mocks.properties</include>
            </includes>
          </testResource>
          <testResource>
            <directory>pasta/recursos-teste</directory>
            <filtering>false</filtering>
            <includes>
              <include>estatic-mocks.properties</include>
            </includes>
          </testResource>
        </testResources>

    Executar o comando e comparar o resultado.

    Podemos ver que agora não aconteceu o mesmo que o plugin. O nossa configuração sobrescreveu a configuração padrão do maven, ou seja, as pastas src/main/resource e src/test/resrouce não estão presentes mais com pastas de recurso.

    Ao cofigurar as tags resources e testResources para criar um novo local, você não pode deixar de finir as pastas padrão das configurações do Maven, caso você tenha arquivos e a utilise no projeto.

    <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>br.com.treinamento</groupId>
      <artifactId>nome-seu-projeto-config</artifactId>
      <version>1.0.0</version>
      ...
      <build>
        <resources>
          <resource>
            <filtering>true</filtering>
            <directory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/pasta/recursos</directory>
            <includes>
              <include>arquivos.properties</include>
            </includes>
          </resource>
          <resource>
            <filtering>false</filtering>
            <directory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/pasta/recursos</directory>
            <includes>
              <include>estaticos.properties</include>
            </includes>
          </resource>
        </resources>
        <testResources>
          <testResource>
            <filtering>true</filtering>
            <directory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/pasta/recursos-teste</directory>
            <includes>
              <include>mocks.properties</include>
            </includes>
          </testResource>
          <testResource>
            <filtering>false</filtering>
            <directory>/home/felipe/Ambiente/projetos/basis/treinamento/fontes/projeto-config/pasta/recursos-teste</directory>
            <includes>
              <include>estatic-mocks.properties</include>
            </includes>
          </testResource>
        </testResources>
        ...
      </build>
    </project>
    • Vamos agora alterar atualizar os plugins usados no nosso build para versões mais recebtes.

      • Utilizando o conceito de gerenciamento de plugins, vamos adicionar as novas versões para alguns que estão sendo usados no build.

        <pluginManagement>
          <plugins>
            <plugin>
              <artifactId>maven-clean-plugin</artifactId>
              <version>3.1.0</version>
            </plugin>
            <plugin>
              <artifactId>maven-resources-plugin</artifactId>
              <version>3.1.0</version>
            </plugin>
            <plugin>
              <artifactId>maven-jar-plugin</artifactId>
              <version>3.2.0</version>
            </plugin>
            <plugin>
              <artifactId>maven-install-plugin</artifactId>
              <version>3.0.0-M1</version>
            </plugin>
            <plugin>
              <artifactId>maven-site-plugin</artifactId>
              <version>3.8.2</version>
            </plugin>
            <plugin>
              <artifactId>maven-deploy-plugin</artifactId>
              <version>3.0.0-M1</version>
            </plugin>
          </plugins>
        </pluginManagement>

    Executar o comando e verifiar a saída.

    Neste o pom.xml foi interpretado e a nossa configuração foi mesclada com a anterior, diferentemente do que aconteceu quando definimos a mais pastas de recursos.

    Veja que na tag plugins do projeto, a versão foi atualizada para que foi adicionada no pluginManagement. Caso você ainda não tenha usado nenhum dessas versões em projetos Mavem, no momento da execução do comando você verá que o downlaod da versão definida no pom.xml vai aparecer no log do BUILD.

    <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>br.com.treinamento</groupId>
      <artifactId>nome-seu-projeto-config</artifactId>
      <version>1.0.0</version>
      ...
      <build>
        ...
        <pluginManagement>
          <plugins>
            <plugin>
              <artifactId>maven-antrun-plugin</artifactId>
              <version>1.3</version>
            </plugin>
            <plugin>
              <artifactId>maven-assembly-plugin</artifactId>
              <version>2.2-beta-5</version>
            </plugin>
            <plugin>
              <artifactId>maven-dependency-plugin</artifactId>
              <version>2.8</version>
            </plugin>
            <plugin>
              <artifactId>maven-release-plugin</artifactId>
              <version>2.5.3</version>
            </plugin>
            <plugin>
              <artifactId>maven-clean-plugin</artifactId>
              <version>3.1.0</version>
            </plugin>
            <plugin>
              <artifactId>maven-resources-plugin</artifactId>
              <version>3.1.0</version>
            </plugin>
            <plugin>
              <artifactId>maven-jar-plugin</artifactId>
              <version>3.2.0</version>
            </plugin>
            <plugin>
              <artifactId>maven-install-plugin</artifactId>
              <version>3.0.0-M1</version>
            </plugin>
            <plugin>
              <artifactId>maven-site-plugin</artifactId>
              <version>3.8.2</version>
            </plugin>
            <plugin>
              <artifactId>maven-deploy-plugin</artifactId>
              <version>3.0.0-M1</version>
            </plugin>
          </plugins>
        </pluginManagement>
        ...
      </build>
      ...
    </project>

    Com isso você aprendeu o básico de configuração dos componetes da TAG de build. Vamos seguir agora para o Ciclo de Vida e os comandos goals que mais serão usados no Maven no seu processo de desenvolvimento.

Maven Build lifecycle

Projetos maven tem 3 processos de Build definidos e cada um tem o seu ciclo de vida que no final não é a morte e sim um artefato ou site de documentação gerado localmente ou remoto, são eles:

  • Default

    • Trabalhar com o processo de compilação, teste e deploy do projeto

  • Clean

    • Trabalhar com o processo de limpeza dos arquivos gerados pelo Default e Site

  • Site

    • Trabalhar com o processo de geração da documentaão do projeto, em formate de um Site que pode ser publicado na WEB.

Build lifecycle - Default

Este é o ciclo mais usado pelos desenvolvedores que trabalham com Maven e onde colocamos a maioria das customizações dos plugins que precisamos.

Dentre as vários passos no ciclo de build default as mais importantes são:

  • validate

    • Validar se todo o necessário para o projeto e seu build estão corretos

  • compile

    • Compilar o código fonte do projeto

  • test

    • Compilar os códigos fontes de teste e executá-los.

  • package

    • Agrupar o conteúdo do artefato no pacote de distruição, no caso um .jar ou .war

  • verify

    • Executar o processo de testes de integração e validação da qualidade do projeto

  • install

    • Copiar o artefato e seu pom.xml para o repositório local do maven, permitindo seu uso em outros projetos locais.

  • deploy

    • Mesmo uqe o Intall, porém em um repositório remoto do maven.

Como o maven trablhar no conceito de Ciclo de Vida, para eu executar o passo verify todos os passos anteriores devem ser executas antes. Assim basta que eu escreva mvn verify e todo o ciclo é executado até o verify.

Para a lista completa de todos os passos do ciclo default, acessar o site Lifecycle_Reference.

Build lifecycle - Site

Este é o ciclo responsável por criar toda a documentação do projeto e também publicar em um servidor remoto.

Phase Descrição

pre-site

Ações necessárias antes da geração da documentação do projeto

site

Gerar a documentação do projeto

post-site

Ações necessárias após a geração do projeto

site-deploy

Deploy em um servidor remoto web da documentação gerada do projeto.

Para executar todos esses passos basta executar o comando: mvn site-deploy

Build lifecycle - Clean

Este Cilco é usado para limpar os arquivos gerados pelos outros Ciclos.

Phase Descrição

pre-clean

Ações necessárias antes de executar a limpeza do projeto

clean

Executa a limpeza do projeto removendo todos os arquivos gerados no build.

post-clean

Ações necessárias após de executar a limpeza do projeto

Para executar todos esses passos basta executar o comando: mvn post-clean

Exercício 1

Vamos praticar agora algums comandos do Ciclo de Vida e verificar o resultado.

Nesse ponto, configurar o settings.xml na pasta ~/.m2 de forma padrão para que seja possível executar o build e comunicar corretamente com o repositório padrão do Maven.
  1. Vamos começar criando o nosso projeto básico.

    1. Criar a pasta do projeto teste-build com o pom.xml defaut:

      <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>br.com.treinamento</groupId>
        <artifactId>teste-build</artifactId>
        <version>1.0.0</version>
      
      </project>
    2. Executar o comando abaixo e verificar as pastas geradas:

      ls -R

      A saída deve ser conforme imagem abaixo:

      background

      A pastas padrão do maven estão criadas e tudo está correto. Vamos agora executar o nosso primeito comando.

  2. Executar os comandos abaixo, que será o mais comum no seu desenvolvimento.

    mvn clean verify
    1. Verificar a saída de log do maven e observar a execução:

      Com apenas 2 comandos (goals) no maven nos fizemos 7 execuções, que estão demarcadas e explicadas abaixo.

      Neste mesmo processo também foi gerado a pasta target, pasta default para os arquivos gerados no processo de build e mais outras pastas dentro desta que são defauls do plugins que foram ativados em cada passo do Ciclo de Vida do build.

      Com esses 2 goals, nos ativamos 2 clicos de vida: Defualt (6 execuções) e o Clean (1 execução)

      [INFO] Scanning for projects...
      [INFO]
      [INFO] -------------------< br.com.treinamento:teste-build >-------------------
      [INFO] Building teste-build 1.0.0
      [INFO] --------------------------------[ jar ]---------------------------------
      [INFO]
      [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ teste-build --- (1)
      [INFO] Deleting /home/felipe/Ambiente/projetos/basis/treinamento/fontes/teste-build/target
      [INFO]
      [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ teste-build --- (2)
      [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
      [INFO] Copying 0 resource
      [INFO]
      [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ teste-build --- (3)
      [INFO] Nothing to compile - all classes are up to date
      [INFO]
      [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ teste-build --- (4)
      [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
      [INFO] Copying 0 resource
      [INFO]
      [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ teste-build --- (5)
      [INFO] Nothing to compile - all classes are up to date
      [INFO]
      [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ teste-build --- (6)
      [INFO]
      [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ teste-build --- (7)
      [INFO] Building jar: /home/felipe/Ambiente/projetos/basis/treinamento/fontes/teste-build/target/teste-build-1.0.0.jar
      [INFO] ------------------------------------------------------------------------
      [INFO] BUILD SUCCESS
      [INFO] ------------------------------------------------------------------------
      [INFO] Total time:  1.643 s
      [INFO] Finished at: 2020-03-06T22:08:31-03:00
      [INFO] ------------------------------------------------------------------------
      1 Execução do passo clean do Clean lifecyle
      2 Execução do passo process-resources do Default lifecyle
      3 Execução do passo compile do Default lifecyle
      4 Execução do passo process-test-resources do Default lifecyle
      5 Execução do passo test-compile do Default lifecyle
      6 Execução do passo test do Default lifecyle
      7 Execução do passo package do Default lifecyle

      Observando essass execuções e os 2 ciclos de vida, Default e Clean o passou por 23 passos no total para gerar esse resultado. Pode ser estranho mais foi isso mesmo que aconteceu. Vamos conferir?

    2. Configurar o plugin maven-antrun-plugin para escrevermos no console.

      Adicionar no projeto a configuração abaixo:

        <build>
          <plugins>
            <plugin>
              <artifactId>maven-antrun-plugin</artifactId>
              <version>1.8</version>
              <executions>
                <execution>
                  <id>clean-passo-pre-clean</id>
                  <phase>pre-clean</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 1 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>clean-passo-clean</id>
                  <phase>clean</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 2 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>clean-passo-post-clean</id>
                  <phase>post-clean</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 3 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-validate</id>
                  <phase>validate</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 4 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-initialize</id>
                  <phase>initialize</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 5 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-generate-sources</id>
                  <phase>generate-sources</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 6 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-process-sources</id>
                  <phase>process-sources</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 7 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-generate-resources</id>
                  <phase>generate-resources</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 8 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-process-resources</id>
                  <phase>process-resources</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 9 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-compile</id>
                  <phase>process-resources</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 10 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-process-classes</id>
                  <phase>process-classes</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 11 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-generate-test-sources</id>
                  <phase>generate-test-sources</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 12 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-process-test-sources</id>
                  <phase>process-test-sources</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 13 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-generate-test-resources</id>
                  <phase>generate-test-resources</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 14 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-process-test-resources</id>
                  <phase>process-test-resources</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 15 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-test-compile</id>
                  <phase>test-compile</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 16 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-process-test-classes</id>
                  <phase>process-test-classes</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 17 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-test</id>
                  <phase>test</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 18 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-prepare-package</id>
                  <phase>prepare-package</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 19 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-package</id>
                  <phase>package</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 20 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-pre-integration-test</id>
                  <phase>pre-integration-test</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 21 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-integration-test</id>
                  <phase>integration-test</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 22 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-post-integration-test</id>
                  <phase>post-integration-test</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 23 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-passo-verify</id>
                  <phase>verify</phase>
                  <configuration>
                    <target>
                      <echo>------ Passo 24 ----</echo>
                    </target>
                  </configuration>
                  <goals>
                    <goal>run</goal>
                  </goals>
                </execution>
              </executions>
            </plugin>
          </plugins>
        </build>

      Executar o comando mvn clean verify verificar se está Ok.

      Para ficar mais fácil de encontrar as informaões no log, vamos executar o comando redirecionando a saída do console para um arquivo de LOG e depois pesquisar pela string ` Passo ` neste log.

      mvn clean verify > teste.log
      cat teste.log | grep ' Passo '

      Pode ser verificado que temos no LOG 23 passos, está faltando somente o Passo 3 do Cliclo de Vida Clean. Execute os comandos abaixo e veja a diferença.

      mvn post-clean verify > teste.log
      cat teste.log | grep ' Passo '

      No comando anterior o passo post-clean não foi executado pois estava depois do passo clean.

  3. Agora vamos tentar desabilitar algumas execuções padrão que temos no nosso pom.xml configurado por default.

    1. Verifique a configuração abaixo que está presente no nosso pom.xml quando executamos o comando mvn help:help:effective-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>br.com.treinamento</groupId>
        <artifactId>teste-build</artifactId>
        <version>1.0.0</version>
        ...
        <build>
          ...
          <plugins>
            ...
            <plugin>
              <artifactId>maven-resources-plugin</artifactId>
              <version>2.6</version>
              <executions>
                <execution>
                  <id>default-testResources</id> (1)
                  <phase>process-test-resources</phase>
                  <goals>
                    <goal>testResources</goal>
                  </goals>
                </execution>
                <execution>
                  <id>default-resources</id> (2)
                  <phase>process-resources</phase>
                  <goals>
                    <goal>resources</goal>
                  </goals>
                </execution>
              </executions>
            </plugin>
          ...
          </plugins>
        </build>
        ...
      </project>
      1 Execution configurado para processar os Recursos
      2 Execution configurado para processar os Recursos de Teste
    2. Existe uma forma de desabilitar execuções, muito útil quando elas estão configuradas em projetos parent, que é feita da forma abaixo e pode ser usado para desabilitar as executions padrão.

            <plugin>
              <artifactId>maven-resources-plugin</artifactId>
              <version>2.6</version>
              <executions>
                <execution>
                  <id>default-testResources</id> (1)
                  <phase>none</phase> (2)
                </execution>
                <execution>
                  <id>default-resources</id> (1)
                  <phase>none</phase> (2)
                </execution>
              </executions>
            </plugin>
      1 Manter a execution com o mesmo ID Execution
      2 Alterar a phase para none

      Ao exexutar o comando você não verá mais no LOG a informação abaixo:

      ...
      
      [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ teste-build ---
      [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
      
      ...
      
      [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ teste-build ---
      [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
      
      ...

      Esse ponto é bem útil caso você deseje desativar algo padrão e configurar de uma outra forma, em outro ponto do Ciclo de Vida.

Desafio Treinamento

TODO Criar um projeto funcional que está compilando corretamente, fora da estrutura de pastas padrão do maven, remover o arquivo pom.xml e solicitar que o projeto seja criado e o comando clean verify executado com sucesso.

Apoio Curso e Desafio