Maven2: Prática recomendada para projeto corporativo (arquivo EAR)

100

Estou apenas mudando do Ant para o Maven e estou tentando descobrir a melhor prática para configurar um projeto corporativo baseado em arquivo EAR.

Digamos que eu queira criar um projeto bastante padrão com um arquivo jar para os EJBs, um arquivo WAR para a camada da Web e o arquivo EAR de encapsulamento, com os descritores de implementação correspondentes.

Como eu faria isso? Crie o projeto comarchetypeArtifactId=maven-archetype-webapp um arquivo war e estender a partir daí? Qual é a melhor estrutura de projeto (e exemplo de arquivo POM) para isso? Onde você coloca os descritores de implantação relacionados ao arquivo ear, etc?

Obrigado por qualquer ajuda.

Maik
fonte

Respostas:

96

Você cria um novo projeto. O novo projeto é seu projeto de montagem EAR, que contém suas duas dependências para seu projeto EJB e seu projeto WAR.

Na verdade, você tem três projetos de maven aqui. Um EJB. One WAR. Uma orelha que une as duas partes e cria a orelha.

Os descritores de implementação podem ser gerados pelo maven ou colocados dentro do diretório de recursos na estrutura do projeto EAR.

O plugin maven-ear é o que você usa para configurá-lo, e a documentação é boa, mas não muito clara se você ainda está descobrindo como o maven funciona em geral.

Então, como exemplo, você pode fazer algo assim:

<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany</groupId>
  <artifactId>myEar</artifactId>
  <packaging>ear</packaging>
  <name>My EAR</name>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-ear-plugin</artifactId>
        <configuration>
          <version>1.4</version>
          <modules>
            <webModule>
              <groupId>com.mycompany</groupId>
              <artifactId>myWar</artifactId>
              <bundleFileName>myWarNameInTheEar.war</bundleFileName>
              <contextRoot>/myWarConext</contextRoot>
            </webModule>
            <ejbModule>
              <groupId>com.mycompany</groupId>
              <artifactId>myEjb</artifactId>
              <bundleFileName>myEjbNameInTheEar.jar</bundleFileName>
            </ejbModule>
          </modules>
          <displayName>My Ear Name displayed in the App Server</displayName>
          <!-- If I want maven to generate the application.xml, set this to true -->
          <generateApplicationXml>true</generateApplicationXml>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.3</version>
        <configuration>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
    </plugins>
    <finalName>myEarName</finalName>
  </build>

  <!-- Define the versions of your ear components here -->
  <dependencies>
    <dependency>
      <groupId>com.mycompany</groupId>
      <artifactId>myWar</artifactId>
      <version>1.0-SNAPSHOT</version>
      <type>war</type>
    </dependency>
    <dependency>
      <groupId>com.mycompany</groupId>
      <artifactId>myEjb</artifactId>
      <version>1.0-SNAPSHOT</version>
      <type>ejb</type>
    </dependency>
  </dependencies>
</project>
Mike Cornell
fonte
98
Eu encontrei minha própria resposta um ano depois, quando fiz a mesma pergunta. Bom trabalho!
Mike Cornell
1
Para mim, isso funcionou quando eu defini typecomoejb <type>ejb</type>
gammay
Esse pom lança alguns avisos: 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-ear-plugin is missinge 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-compiler-plugin is missing, então, talvez você queira atualizar sua resposta excelente
DiegoAlfonso
46

O que me ajudou muito foi executar o arquétipo do Maven: gerar meta e selecionar um dos arquétipos, alguns dos quais parecem ser atualizados regularmente (em particular, o JBoss parece estar bem mantido).

mvn archetype:generate

Centenas de arquétipos apareceram em uma lista numerada para seleção (519 a partir de agora!). O objetivo, ainda em execução, me levou a fazer uma seleção inserindo um número ou uma string de pesquisa, por exemplo:

513: remote -> org.xwiki.commons:xwiki-commons-component-archetype
514: remote -> org.xwiki.rendering:xwiki-rendering-archetype-macro
515: remote -> org.zkoss:zk-archetype-component
516: remote -> org.zkoss:zk-archetype-webapp
517: remote -> ru.circumflex:circumflex-archetype (-)
518: remote -> se.vgregion.javg.maven.archetypes:javg-minimal-archetype (-)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains):

Eu digitei a string de pesquisa "orelha", que reduziu a lista a apenas 8 itens (até hoje):

Choose archetype:
1: remote -> org.codehaus.mojo.archetypes:ear-j2ee14 (-)
2: remote -> org.codehaus.mojo.archetypes:ear-javaee6 (-)
3: remote -> org.codehaus.mojo.archetypes:ear-jee5 (-)
4: remote -> org.hibernate:hibernate-search-quickstart (-)
5: remote -> org.jboss.spec.archetypes:jboss-javaee6-ear-webapp 
6: remote -> org.jboss.spec.archetypes:jboss-javaee6-webapp-ear-archetype
7: remote -> org.jboss.spec.archetypes:jboss-javaee6-webapp-ear-archetype-blank
8: remote -> org.ow2.weblab.tools.maven:weblab-archetype-searcher

Selecionei "org.jboss.spec.archetypes: jboss-javaee6-ear-webapp" (inserindo a seleção "5" neste exemplo).

Em seguida, a meta me pediu para inserir o groupId, o artifactId, os nomes dos pacotes, etc., e então gerou o seguinte aplicativo de exemplo bem documentado:

[pgarner@localhost Foo]$ tree
.
|-- Foo-ear
|   `-- pom.xml
|-- Foo-ejb
|   |-- pom.xml
|   `-- src
|       |-- main
|       |   |-- java
|       |   |   `-- com
|       |   |       `-- foo
|       |   |           |-- controller
|       |   |           |   `-- MemberRegistration.java
|       |   |           |-- data
|       |   |           |   `-- MemberListProducer.java
|       |   |           |-- model
|       |   |           |   `-- Member.java
|       |   |           `-- util
|       |   |               `-- Resources.java
|       |   `-- resources
|       |       |-- import.sql
|       |       `-- META-INF
|       |           |-- beans.xml
|       |           `-- persistence.xml
|       `-- test
|           |-- java
|           |   `-- com
|           |       `-- foo
|           |           `-- test
|           |               `-- MemberRegistrationTest.java
|           `-- resources
|-- Foo-web
|   |-- pom.xml
|   `-- src
|       `-- main
|           |-- java
|           |   `-- com
|           |       `-- foo
|           |           `-- rest
|           |               |-- JaxRsActivator.java
|           |               `-- MemberResourceRESTService.java
|           `-- webapp
|               |-- index.html
|               |-- index.xhtml
|               |-- resources
|               |   |-- css
|               |   |   `-- screen.css
|               |   `-- gfx
|               |       |-- banner.png
|               |       `-- logo.png
|               `-- WEB-INF
|                   |-- beans.xml
|                   |-- faces-config.xml
|                   `-- templates
|                       `-- default.xhtml
|-- pom.xml
`-- README.md

32 directories, 23 files

Depois de ler os quatro arquivos POM, que foram bem comentados, eu tinha praticamente todas as informações de que precisava.

./pom.xml
./Foo-ear/pom.xml
./Foo-ejb/pom.xml
./Foo-web/pom.xml
Patrick Garner
fonte
3
Isso funciona, mas acaba colocando um monte de dependências específicas do jboss em seu projeto, que você pode ou não querer limpar após o fato.
Ian McLaird
24

Eu fiz um repositório github para mostrar o que eu acho que é uma boa (ou melhores práticas) estrutura de projeto de inicialização ...

https://github.com/StefanHeimberg/stackoverflow-1134894

algumas palavras-chave:

  • Maven 3
  • BOM (Gerenciamento de Dependências das próprias dependências)
  • Pai para todos os projetos (DependencyManagement de dependências externas e PluginManagement para configuração global do projeto)
  • JUnit / Mockito / DBUnit
  • Limpe o projeto War sem WEB-INF / lib porque as dependências estão na pasta EAR / lib.
  • Projeto Clean Ear.
  • Descritores mínimos de implantação para Java EE7
  • Sem interface EJB local porque @LocalBean é suficiente.
  • Configuração mínima do maven por meio das propriedades do usuário do maven
  • Descritores de implantação reais para Servlet 3.1 / EJB 3.2 / JPA 2.1
  • uso do plugin macker-maven para verificar as regras de arquitetura
  • Testes de integração ativados, mas ignorados. (skipITs = false) útil para ativar no CI Build Server

Saída Maven:

Reactor Summary:

MyProject - BOM .................................... SUCCESS [  0.494 s]
MyProject - Parent ................................. SUCCESS [  0.330 s]
MyProject - Common ................................. SUCCESS [  3.498 s]
MyProject - Persistence ............................ SUCCESS [  1.045 s]
MyProject - Business ............................... SUCCESS [  1.233 s]
MyProject - Web .................................... SUCCESS [  1.330 s]
MyProject - Application ............................ SUCCESS [  0.679 s]
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time: 8.817 s
Finished at: 2015-01-27T00:51:59+01:00
Final Memory: 24M/207M
------------------------------------------------------------------------
StefanHeimberg
fonte
2
Eu realmente gosto de sua abordagem de embalagem e arquitetura. Você deve pensar em empacotar seu projeto como um arquétipo de maven.
Jörg
2
Solução muito boa! Porém, tenho uma pergunta: por que não incluir o material de BOM no projeto pai? por que a camada adicional?
sschober
1
causa da separação de interesses. o BOM poderia ser importado por outros projetos. eles precisam apenas do dependencyManagement de suas dependências e não do dependencyManagement das dependências que você está usando. Está bem. você pode dizer que se ninguém estiver usando seu projeto esta camada adicional não é necessária .. mas eu acho que faz sentido também ... legibilidade. o dependencyManagement do projeto pai não está misturado com suas dependências ... em um projeto maior com> 50 projetos maven internos, o dependencyManagement dentro do projeto pai pode ser uma bagunça ..
StefanHeimberg
2
outro motivo é que esta é a mesma estrutura documentada em maven.apache.org/guides/introduction/… . isso ajuda a trabalhar em uma equipe em que os membros da equipe mudam frequentemente porque é a forma "padrão" documentada.
StefanHeimberg
2
BTW. Eu criei um projeto GitHub uma vez para mostrar como uma configuração de vários projetos poderia ser feita: github.com/StefanHeimberg/maven3-multiapplication-setup (para uma discussão interna da empresa)
StefanHeimberg
7

O NetBeans IDE define automaticamente a estrutura que é quase semelhante à sugerida por Patrick Garner. Para usuários NetBeans

Arquivo -> Novo projeto -> No lado esquerdo, selecione Maven e, no lado direito, selecione Maven Enterprise Application e pressione Avançar -> Solicita nomes de projeto para war, ejb e configurações.

O IDE criará automaticamente a estrutura para você.

stackOverflow
fonte
Eu concordo com você, especialmente quando aderindo às especificações JEE6
Sym-Sym
3

Este é um bom exemplo da parte do plugin maven-ear .

Você também pode verificar os arquétipos maven que estão disponíveis como exemplo. Se você apenas executar runt mvn archetype: generate, você obterá uma lista de arquétipos disponíveis. Uma delas é

maven-archetype-j2ee-simple
hcpl
fonte
10
maven-archetype-j2ee-simpleparece desnecessariamente complexo em estrutura - particularmente com módulos dentro de módulos e módulos separados para coisas como registro. Eu não entendi a lógica por trás dessa estrutura
Vihung
2

Eu tenho pesquisado de alto a baixo por um exemplo ponta a ponta de um aplicativo completo com pacote auricular baseado em maven e, finalmente, encontrei isso . As instruções dizem para selecionar a opção 2 ao executar através da CLI, mas para seus propósitos, use a opção 1.

Roy Truelove
fonte
O link gera um erro não autorizado. E essa é a razão para escrever soluções completas em vez de depender de links.
Paco Abato