Maven não reconhece módulos irmãos ao executar mvn dependency: tree

90

Estou tentando configurar um projeto Maven com vários módulos e as dependências entre os módulos aparentemente não estão sendo configuradas corretamente.

Eu tenho:

<modules>
  <module>commons</module>
  <module>storage</module>
</modules>

no POM pai (que tem um pom do tipo de embalagem) e, em seguida, nos subdiretórios commons/e storage/que definem os poms JAR com o mesmo nome.

O armazenamento depende do Commons.

No diretório principal (mestre), executo mvn dependency:treee vejo:

[INFO] Building system
[INFO]    task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:tree {execution: default-cli}]
[INFO] domain:system:pom:1.0-SNAPSHOT
[INFO] \- junit:junit:jar:3.8.1:test
[INFO] ------------------------------------------------------------------------
[INFO] Building commons
[INFO]    task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:tree {execution: default-cli}]
...correct tree...
[INFO] ------------------------------------------------------------------------
[INFO] Building storage
[INFO]    task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
Downloading: http://my.repo/artifactory/repo/domain/commons/1.0-SNAPSHOT/commons-1.0-SNAPSHOT.jar
[INFO] Unable to find resource 'domain:commons:jar:1.0-SNAPSHOT' in repository my.repo (http://my.repo/artifactory/repo)
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.

Missing:
----------
1) domain:commons:jar:1.0-SNAPSHOT

Por que a dependência de "bens comuns" falha, embora o reator obviamente a tenha visto porque processa com sucesso sua árvore de dependência? Definitivamente, não deveria ir para a rede para encontrá-lo, pois está bem ali ...

O pom para armazenamento:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <packaging>jar</packaging>
  <parent>
    <artifactId>system</artifactId>
    <groupId>domain</groupId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <groupId>domain</groupId>
  <artifactId>storage</artifactId>
  <name>storage</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <!-- module dependencies -->
    <dependency>
      <groupId>domain</groupId>
      <artifactId>commons</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>

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

Obrigado por qualquer sugestão!

(Editar)

Para esclarecer, o que estou procurando aqui é o seguinte: Não quero ter que instalar o módulo X para construir o módulo Y que depende de X, visto que ambos são módulos referenciados no mesmo POM pai. Isso faz sentido intuitivo para mim que, se eu tiver duas coisas na mesma árvore de origem, não devo ter que instalar produtos intermediários para continuar a compilação. Espero que meu pensamento faça algum sentido aqui ...

Steven Schlansker
fonte
2
Ahhh, a edição é perfeita. Por que você não escreveu isso na primeira intenção? Além disso, talvez considere alterar o título :) Não quero ser exigente, é apenas por uma questão de clareza e classificação. Isso ajudará toda a comunidade no futuro na busca por um problema semelhante (que não está claro com o título real e o conteúdo sobre dependência: árvore)
Pascal Thivent
1
Oi. Você encontrou a solução? Também tenho esse problema :(
1
A compilação falha ou apenas a dependência: objetivo da árvore sozinho? Veja a resposta de Don Willis.
metamatt
OMG então em um módulo se ele falhar porque não consegue encontrar símbolos de outro módulo, o outro deve ser adicionado como dependência e instalado como JAR? Esta é a chave ...
WesternGun
é triste que o maven 3.6 ainda não resolve este problema
yuxh

Respostas:

21

Acho que o problema é que, quando você especifica uma dependência, o Maven espera tê-la como jar (ou qualquer outro) empacotado e disponível em pelo menos um repositório local. Tenho certeza de que se você executar primeiro mvn installem seu projeto comum, tudo funcionará.

Bostone
fonte
4
Existe uma maneira de especificar que desejo usar qualquer versão do módulo que esteja na árvore de origem? Achei que esse caso seria tratado automaticamente. Eu não quero / não acho que o Maven precisa ter que construir-instalar-construir-instalar-construir toda vez que eu só quero fazer o projeto inteiro!
Steven Schlansker
38
Você está correto que a execução de instalação corrige isso. Porém, agora tenho que instalar toda vez que faço alterações, o que não é o que desejo. Eu quero que o projeto de armazenamento pegue o código mais recente do projeto commons.
Steven Schlansker
Na verdade, tenho que lidar com questões semelhantes e, infelizmente - não consegui encontrar uma resposta até agora. Parece que o Maven não se importa se a dependência está vinculada ao seu módulo, ela apenas vai para o repositório imediatamente. Vou colocar sua pergunta como favorita - então talvez algum guru responda. Estou interessado em saber se isso pode ser feito
Bostone
@Steven Por favor, poste sua preocupação como outra pergunta, não é útil responder em um comentário e este é outro assunto.
Pascal Thivent
6
Essa era a questão principal, eu estava simplesmente esclarecendo. Não deixei claro na pergunta original que minha intenção é não exigir que os produtos construídos estejam no repositório local para construir outros módulos no mesmo projeto?
Steven Schlansker
104

Conforme discutido neste tópico da lista de discussão maven , o objetivo da dependência: árvore por si só procurará as coisas no repositório ao invés do reator. Você pode contornar isso instalando mvn, conforme sugerido anteriormente, ou fazendo algo menos oneroso que invoque o reator, como

mvn compile dependency:tree

Funciona para mim.

Don Willis
fonte
2
Obrigado por essa solução alternativa barata. Mas é um bug? Espero dependência: o objetivo da árvore depende do reator sem nenhum truque.
mcoolive
Deve-se observar que a mesma situação acontece para qualquer tarefa executada globalmente, mas afeta apenas alguns subprojetos.
tkruse
Infelizmente, compiledispara o download de dependências transitivas. Existe também uma maneira de listar a árvore de dependências sem realmente baixá-los (exceto os POMs, é claro)?
sschuberth
Eu tive o mesmo problema para outros objetivos. Adicionar compile( validatenão é suficiente) ajudou também: mvn compile animal-sniffer:checkemvn compile org.basepom.maven:duplicate-finder-maven-plugin:check
msa
Dependendo de sua construção, alguns Módulos também podem ter dependências para artefatos que são construídos em fases posteriores. No meu caso, um arquivo ZIP (usando maven-assembly-plugin) foi construído na packagefase, então eu precisei fazer, por exemplo mvn package animal-sniffer:check.
msa
6

Perceber isso é um tópico mais antigo, mas parece que a ferramenta evoluiu ou isso pode ter sido esquecido da primeira vez.

É possível realizar uma construção que faça dependências resolvidas sem instalar, fazendo uma construção de reator.

Se você iniciar sua construção no pai que descreve a estrutura do módulo do seu projeto, suas dependências entre os módulos serão resolvidas durante a própria construção por meio do reator interno Maven.

Claro que esta não é a solução perfeita, pois não resolve a construção de um único módulo individual dentro da estrutura. Neste caso o Maven não terá as dependências em seu reator e buscará resolvê-lo no repositório. Portanto, para compilações individuais, você ainda precisa instalar as dependências primeiro.

Aqui estão algumas referências que descrevem esta situação.

Newtopian
fonte
1
Existe alguma maneira de construir um único módulo, sem instalar as dependências primeiro e sem construir o projeto pai completo?
QUIT - Anony-Mousse de
1
Para completar a resposta - se o plugin for invocado diretamente (sem fases) mvn dependency:tree, por exemplo , ele ainda não resolverá as dependências das fontes a menos que você invoque a compilefase. Então, isso iria funcionar em vez disso: mvn compile dependency:tree.
Stanislav Bashkyrtsev
3

para mim, o que me levou a este tópico foi um problema semelhante e a solução foi garantir que todas as dependências do módulo tivessem

 <packaging>pom</packaging>

o pai tinha

pom

meu modelo dep tinha pom - então não havia jarra a ser encontrada.

bsautner
fonte
Isso gera este erro para mim: Erro de análise ao ler POM. Motivo: tag não reconhecida: 'embalagem'
hithwen
editar: eu quis dizer que <packaging> pom </packaging> consertou. substituindo <packaging> jar </packaging>
bsautner
4
Isso corrige o problema descrito na pergunta, mas agora os módulos filhos não produzem arquivos exportáveis ​​(ou seja, jars, wars, ear).
sheldonh
sheldonh você encontrou uma solução para corrigir esse erro e produzir um arquivo exportável?
user3853134
3

A única coisa que funcionou para mim: mudar para o gradle :(

eu tenho

Parent
  +---dep1
  +---war1 (using dep1)

e posso apenas fazer cd em war1 e usar mvn tomcat7: run-war. Sempre tenho que instalar o projeto inteiro antes, apesar das referências de war1, seu pai e as referências do pai war1 e dep1 (como módulos), então todas as dependências devem ser conhecidas.

Não entendo qual é o problema.

mba
fonte
1
É por isso que eu uso o Gradle quando tenho que criar um projeto com vários módulos. :(
Zhuo YING
2

Em uma estrutura de módulo Maven como esta:

- parent
  - child1
  - child2

Você terá parent pomneste:

<modules>
  <module>child1</module>
  <module>child2</module>
</modules>

Se você agora dependem child1em child2, colocando o seguinte no seu <dependencies>em child2:

<dependency>
  <groupId>example</groupId>
  <artifactId>child1</artifactId>
</dependency>

Você receberá um erro no qual o JAR child1não pode ser encontrado. Isso pode ser resolvido declarando um <dependencyManagement>bloco incluindo child1no pomfor parent:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>example</groupId>
      <artifactId>child1</artifactId>
      <version>${project.version}</version>
    </dependency>
  </dependencies>
</dependencyManagement>

child1agora será compilado quando você executar um objetivo compileou packageetc. no parent, e child2encontrará child1os arquivos compilados de.

bothor
fonte
2

Bonificando a resposta de Don Willis :

Se sua compilação cria jars de teste para compartilhar o código de teste entre os submódulos do reator, você deve usar:

mvn test-compile dependency:tree

que permitirá dependency:treea execução até a conclusão neste caso.

adrock20
fonte
-1

Certifique-se de que o módulo que está falhando seja resolvido no pom, esteja apontando para o pai correto, incluindo as configurações no arquivo pom do módulo.

Nitin Kamate
fonte