Maven no reconoce los módulos hermanos al ejecutar la dependencia de mvn: árbol

90

Estoy tratando de configurar un proyecto Maven de varios módulos, y las dependencias entre módulos aparentemente no se están configurando correctamente.

Yo tengo:

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

en el POM padre (que tiene un pom de tipo empaquetado) y luego en los subdirectorios commons/y storage/que definen los poms JAR con el mismo nombre.

El almacenamiento depende de Commons.

En el directorio principal (maestro), ejecuto mvn dependency:treey veo:

[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 qué falla la dependencia de los "comunes", a pesar de que el reactor obviamente lo ha visto porque procesa con éxito su árbol de dependencia? Definitivamente no debería ir a la red para encontrarlo, ya que está allí ...

El pom para almacenamiento:

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

¡Gracias por cualquier sugerencia!

(Editar)

Para aclarar, lo que estoy buscando aquí es esto: no quiero tener que instalar el módulo X para construir el módulo Y que depende de X, dado que ambos son módulos referenciados desde el mismo POM principal. Esto tiene sentido intuitivo para mí que si tengo dos cosas en el mismo árbol de fuentes, no debería tener que instalar productos intermedios para continuar con la compilación. Ojalá mi pensamiento tenga algún sentido aquí ...

Steven Schlansker
fuente
2
Ahhh, la edición es perfecta. ¿Por qué no escribiste esto en la primera intención? Además, quizás considere cambiar el título :) No quiero ser exigente, esto es solo por claridad y clasificación. Esto ayudará a toda la comunidad en el futuro cuando busque un problema similar (que no es claro como el cristal con el título real y el contenido que trata sobre la dependencia: árbol)
Pascal Thivent
1
Hola. ¿Encontraste la solución? También tengo este problema :(
1
¿La compilación falla, o solo la dependencia: objetivo del árbol solo? Vea la respuesta de Don Willis.
metamatt
Dios mío, entonces, en un módulo si falla porque no puede encontrar símbolos de otro módulo, ¿el otro debe agregarse como dependencia e instalarse como JAR? Esta es la clave ...
WesternGun
es triste que maven 3.6 aún no resuelva este problema
yuxh

Respuestas:

21

Creo que el problema es que cuando especificas una dependencia, Maven espera tenerla empaquetada como jar (o lo que sea) y disponible en al menos un repositorio local. Estoy seguro de que si ejecuta mvn installprimero su proyecto de bienes comunes, todo funcionará.

Bostone
fuente
4
¿Hay alguna forma de especificar que quiero que use cualquier versión del módulo que esté en el árbol de fuentes? Pensé que este caso se manejaría automáticamente. No quiero / no creo que Maven requiera tener que construir-instalar-construir-instalar-construir cada vez que solo quiero hacer el proyecto completo.
Steven Schlansker
38
Tiene razón en que ejecutar la instalación lo corrige. Sin embargo, ahora tengo que instalar cada vez que hago cambios, que no es lo que quiero. Quiero que el proyecto de almacenamiento recoja el último código del proyecto commons.
Steven Schlansker
De hecho, tengo que lidiar con problemas similares y, por desgracia, no puedo encontrar una respuesta hasta ahora. Parece que a Maven no le importa que la dependencia esté vinculada a su módulo, simplemente va al repositorio de inmediato. Pondré favorito a tu pregunta, así que tal vez algún gurú responda. Me interesa saber si se puede hacer esto
Bostone
@Steven Por favor publique su preocupación como otra pregunta, no es útil responder en un comentario y este es otro tema.
Pascal Thivent
6
Se suponía que esa era la pregunta principal, simplemente estaba aclarando. ¿No dejé en claro en la pregunta original que mi intención es no requerir que los productos construidos estén en el repositorio local para construir otros módulos en el mismo proyecto?
Steven Schlansker
104

Como se discutió en este hilo de la lista de correo de Maven , el objetivo de dependencia: árbol por sí solo buscará cosas en el repositorio en lugar de en el reactor. Puede solucionar esto instalando mvn, como se sugirió anteriormente, o haciendo algo menos oneroso que invoca el reactor, como

mvn compile dependency:tree

Funciona para mi.

Don Willis
fuente
2
Gracias por esa solución barata. ¿Pero es un error? Espero dependencia: el objetivo del árbol se basa en el reactor sin ningún truco.
mcoolive
Cabe señalar que ocurre lo mismo con cualquier tarea que se ejecute globalmente, pero solo afecta a algunos subproyectos.
tkruse
Desafortunadamente, compiledesencadena la descarga de dependencias transitivas. ¿Existe también una forma de enumerar el árbol de dependencias sin descargarlos realmente (excepto los POM, por supuesto)?
sschuberth
Tuve el mismo problema para otros objetivos. Agregar compile( validateno es suficiente) ayudó allí también: mvn compile animal-sniffer:checkymvn compile org.basepom.maven:duplicate-finder-maven-plugin:check
msa
Dependiendo de su compilación, algunos módulos también pueden tener dependencias de artefactos que se compilan en fases posteriores. En mi caso, un archivo ZIP (usando maven-assembly-plugin) se construyó en packagefase, por lo que necesitaba hacerlo, por ejemplo mvn package animal-sniffer:check.
misa
6

Darse cuenta de que este es un hilo más antiguo, pero parece que la herramienta evolucionó o esto podría haberse perdido la primera vez.

Es posible realizar una compilación que resuelva las dependencias sin instalar mediante una compilación de reactor.

Si comienza su compilación en el padre que describe la estructura del módulo de su proyecto, sus dependencias entre sus módulos se resolverán durante la compilación a través del reactor interno de Maven.

Por supuesto, esta no es la solución perfecta, ya que no resuelve la construcción de un solo módulo individual dentro de la estructura. En este caso, Maven no tendrá las dependencias en su reactor y buscará resolverlo en el repositorio. Entonces, para compilaciones individuales, aún debe instalar las dependencias primero.

Aquí hay alguna referencia que describe esta situación.

Newtopian
fuente
1
¿Hay alguna forma de construir un solo módulo, sin instalar primero las dependencias y sin construir el proyecto principal completo?
Ha QUIT - Anony-Mousse
1
Para completar la respuesta, si el complemento se invoca directamente (sin fases) mvn dependency:tree, por ejemplo , aún no resolverá las dependencias de las fuentes a menos que invoque la compilefase. Así que esto funcionaría en su lugar: mvn compile dependency:tree.
Stanislav Bashkyrtsev
3

para mí, lo que me llevó a este hilo fue un problema similar y la solución fue asegurar que todos los pom de dependencia del módulo tuvieran

 <packaging>pom</packaging>

el padre tenía

pom

mi modelo de depósito tenía pom, por lo que no se encontró ningún frasco.

bsautner
fuente
Eso me arroja este error: Parse error reading POM. Motivo: Etiqueta no reconocida: 'empaquetado'
hithwen
editar: quise decir <packaging> pom </packaging> lo arregló. reemplazando <packaging> jar </packaging>
bsautner
4
Esto soluciona el problema descrito en la pregunta, pero ahora los módulos secundarios no producen archivos exportables (es decir, jarras, guerras, oídos).
sheldonh
sheldonh, ¿encontró una solución para corregir este error y producir un archivo exportable?
user3853134
3

Lo único que funcionó para mí: cambiar a gradle :(

yo tengo

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

y puedo simplemente cd en war1 y usar mvn tomcat7: run-war. Siempre tengo que instalar todo el proyecto antes, a pesar de que war1 hace referencia a su padre y el padre hace referencia a war1 y dep1 (como módulos), por lo que se deben conocer todas las dependencias.

No entiendo cuál es el problema.

MBA
fuente
1
Es por eso que uso gradle cuando tengo que crear un proyecto de varios módulos. :(
Zhuo YING
2

En una estructura de módulo de Maven como esta:

- parent
  - child1
  - child2

Tendrás en el parent pomesto:

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

Si ahora depende de child1adentro child2poniendo lo siguiente en su <dependencies>adentro child2:

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

Recibirá un error que indica que child1no se puede encontrar el JAR . Esto se puede resolver declarando un <dependencyManagement>bloque que incluya child1en el pomfor parent:

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

child1ahora se compilará cuando ejecute un objetivo compileo packageetc. en parent, y child2encontrará child1los archivos compilados de.

ambos o
fuente
2

Bonificación de la respuesta de Don Willis :

Si su compilación crea jarras de prueba para compartir código de prueba entre sus submódulos de reactor, debe usar:

mvn test-compile dependency:tree

lo que permitirá dependency:treeque se ejecute hasta su finalización en este caso.

adrock20
fuente
-1

Asegúrese de que el módulo que está fallando se resuelva en el pom, esté apuntando al padre correcto al incluir las configuraciones en el archivo pom del módulo.

Nitin Kamate
fuente