Parece haver várias maneiras de estruturar os pais-pais em uma compilação de multiprojetos e eu me pergunto se alguém pensou sobre quais são as vantagens / desvantagens de cada maneira.
O método mais simples de ter um pom pai seria colocá-lo na raiz de um projeto, ou seja,
myproject/
myproject-core/
myproject-api/
myproject-app/
pom.xml
em que pom.xml é o projeto pai e descreve os módulos -core -api e -app
O próximo método é separar o pai em seu próprio subdiretório, como em
myproject/
mypoject-parent/
pom.xml
myproject-core/
myproject-api/
myproject-app/
Onde o pom pai ainda contém os módulos, mas eles são relativos, por exemplo ../myproject-core
Finalmente, há a opção em que a definição do módulo e o pai são separados como em
myproject/
mypoject-parent/
pom.xml
myproject-core/
myproject-api/
myproject-app/
pom.xml
Onde o pom principal contém qualquer configuração "compartilhada" (dependencyManagement, propriedades etc.) e o myproject / pom.xml contém a lista de módulos.
A intenção é ser escalável para uma construção em larga escala, portanto deve ser escalável para um grande número de projetos e artefatos.
Algumas perguntas bônus:
- Onde é o melhor lugar para definir as várias configurações compartilhadas como no controle de origem, diretórios de implantação, plug-ins comuns etc. (estou assumindo que o pai, mas muitas vezes fui mordido por isso e eles acabaram em cada projeto em vez de comum).
- Como o plugin maven-release, hudson e nexus lidam com a maneira como você configura seus multiprojetos (possivelmente uma pergunta gigante, é mais se alguém foi pego quando, pela forma como uma compilação de multiprojetos foi criada)?
Edit: Cada um dos subprojetos tem seu próprio pom.xml, deixei de fora para mantê-lo conciso.
fonte
Respostas:
Na minha opinião, para responder a essa pergunta, você precisa pensar em termos de ciclo de vida do projeto e controle de versão. Em outras palavras, o pom pai tem seu próprio ciclo de vida, ou seja, pode ser liberado separadamente dos outros módulos ou não?
Se a resposta for sim (e este é o caso da maioria dos projetos mencionados na pergunta ou nos comentários), o pai pai precisa de seu próprio módulo a partir de um VCS e do ponto de vista do Maven e você acabará com algo parecido com isto no nível VCS:
Isso torna o checkout um pouco doloroso e é uma maneira comum de lidar com isso
svn:externals
. Por exemplo, adicione umtrunks
diretório:Com a seguinte definição externa:
Um checkout de
trunks
resultaria na seguinte estrutura local (padrão # 2):Opcionalmente, você pode até adicionar um
pom.xml
notrunks
diretório:Este
pom.xml
é um tipo de pom "falso": nunca é lançado, não contém uma versão real, pois esse arquivo nunca é lançado, contém apenas uma lista de módulos. Com esse arquivo, um checkout resultaria nessa estrutura (padrão nº 3):Esse "hack" permite o lançamento de uma construção de reator a partir da raiz após um checkout e torna as coisas ainda mais úteis. Na verdade, é assim que eu gosto de configurar projetos maven e um repositório VCS para grandes compilações : ele simplesmente funciona, dimensiona bem, oferece toda a flexibilidade que você pode precisar.
Se a resposta for não (de volta à pergunta inicial), acho que você pode viver com o padrão nº 1 (faça a coisa mais simples que possa funcionar).
Agora, sobre as perguntas de bônus:
Honestamente, não sei como não dar uma resposta geral aqui (como "use o nível em que você acha que faz sentido mútuo"). De qualquer forma, os filhos-filhos sempre podem substituir as configurações herdadas.
A configuração que eu uso funciona bem, nada de especial a ser mencionado.
Na verdade, eu me pergunto como o maven-release-plugin lida com o padrão nº 1 (especialmente com a
<parent>
seção, pois você não pode ter dependências do INSTANTÂNEO no momento do lançamento). Parece um problema de galinha ou ovo, mas não consigo me lembrar se funciona e estava com preguiça de testá-lo.fonte
Pela minha experiência e pelas melhores práticas do Maven, existem dois tipos de "pais-pais"
pom principal da "empresa" - esse pom contém informações e configurações específicas da sua empresa que herdam cada pom e não precisam ser copiadas. Essas informações são:
A preparação deste pom pai precisa ser feita com cautela, porque todos os documentos da sua empresa herdarão dele, portanto esse pom deve ser maduro e estável (a liberação de uma versão do pom pai não deve afetar a liberação de todos os projetos da sua empresa!)
Os projetos múltiplos têm estrutura de árvores - portanto, você não é levado a um nível de pom-pai. Tente encontrar uma estrutura de projeto adequada para suas necessidades - um exemplo clássico é como descrever projetos de mutimódulos
Essa configuração deve ser sabiamente dividida em pom principal da "empresa" e pom (s) pai do projeto. As coisas relacionadas a tudo o que você projeta vão para o pai da "empresa" e as relacionadas ao projeto atual vão para o projeto de alguém.
O pai da empresa deve ser lançado primeiro. Para multiprojetos, aplicam-se regras padrão. O servidor de CI precisa conhecer tudo para criar o projeto corretamente.
fonte
Um pai independente é a melhor prática para compartilhar configurações e opções entre componentes desacoplados. O Apache possui um projeto pai pom para compartilhar avisos legais e algumas opções comuns de empacotamento.
Se o seu projeto de nível superior tiver um trabalho real, como agregar javadoc ou empacotar um release, você terá conflitos entre as configurações necessárias para executar esse trabalho e as que deseja compartilhar via pai. Um projeto somente pai evita isso.
Um padrão comum (ignorando o nº 1 no momento) é fazer com que os projetos com código usem um projeto pai como pai e o nível superior como pai. Isso permite que os principais itens sejam compartilhados por todos, mas evita o problema descrito no item 2.
O plugin do site ficará muito confuso se a estrutura pai não for a mesma que a estrutura de diretórios. Se você deseja criar um site agregado, precisará fazer algumas manobras para contornar isso.
O Apache CXF é um exemplo do padrão em # 2.
fonte
Há um pequeno problema com a terceira abordagem. Como as POMs agregadas (myproject / pom.xml) geralmente não têm pai, elas não compartilham a configuração. Isso significa que todos esses POMs agregados terão apenas repositórios padrão.
Isso não é um problema se você usar apenas plug-ins do Central; no entanto, isso falhará se você executar o plugin usando o formato plugin: goal do seu repositório interno. Por exemplo, você pode ter
foo-maven-plugin
com o groupId deorg.example
fornecer metagenerate-foo
. Se você tentar executá-lo a partir da raiz do projeto usando o comando likemvn org.example:foo-maven-plugin:generate-foo
, ele falhará ao ser executado nos módulos agregados (consulte a nota de compatibilidade ).Várias soluções são possíveis:
fonte