Maven nie rozpoznaje modułów siostrzanych podczas uruchamiania zależności mvn: drzewo

90

Próbuję skonfigurować wielomodułowy projekt Maven, a zależności między modułami najwyraźniej nie są poprawnie konfigurowane.

Mam:

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

w POM macierzystego (który opakowanie typu POM), a następnie podkatalogów commons/i storage/które określają poms słoik z tej samej nazwie.

Miejsce na dane zależy od Commons.

W katalogu głównym (głównym) uruchamiam mvn dependency:treei widzę:

[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

Dlaczego zależność od „wspólnych” zawodzi, mimo że reaktor najwyraźniej ją zauważył, ponieważ pomyślnie przetwarza swoje drzewo zależności? Zdecydowanie nie powinien iść do sieci, aby go znaleźć, ponieważ jest tam ...

Pom do przechowywania:

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

Dzięki za wszelkie sugestie!

(Edytować)

Aby wyjaśnić, czego tutaj szukam, jest to: nie chcę instalować modułu X, aby zbudować moduł Y, który zależy od X, biorąc pod uwagę, że oba są modułami, do których odwołuje się ten sam nadrzędny POM. Ma to dla mnie intuicyjny sens, że jeśli mam dwie rzeczy w tym samym drzewie źródłowym, nie powinienem instalować produktów pośrednich, aby kontynuować kompilację. Mam nadzieję, że moje myślenie ma tutaj jakiś sens ...

Steven Schlansker
źródło
2
Ahhh, Edycja jest idealna. Dlaczego nie napisałeś tego w pierwszej intencji? Może też rozważ zmianę tytułu :) Nie chcę być wybredny, to tylko dla jasności i klasyfikacji. Pomoże to całej społeczności w przyszłości w poszukiwaniu podobnego problemu (co nie jest krystalicznie jasne w przypadku faktycznego tytułu i treści, która dotyczy zależności: drzewo)
Pascal Thivent
1
Cześć. Czy znalazłeś rozwiązanie? Też mam ten problem :(
1
Czy kompilacja kończy się niepowodzeniem, czy tylko zależność: sam cel drzewa? Zobacz odpowiedź Don Willisa.
metamatt
OMG więc w jednym module, jeśli zawiedzie, ponieważ nie może znaleźć symboli innego modułu, drugi powinien zostać dodany jako zależność i zainstalowany jako JAR? To jest klucz ...
WesternGun
To smutne maven 3.6 jeszcze nie rozwiązuje tego problemu
yuxh

Odpowiedzi:

21

Myślę, że problem polega na tym, że kiedy określasz zależność, Maven spodziewa się, że będzie ona zapakowana jako jar (lub cokolwiek innego) i będzie dostępna przynajmniej z lokalnego repozytorium. Jestem pewien, że jeśli najpierw uruchomisz mvn installswój wspólny projekt, wszystko będzie działać.

Bostone
źródło
4
Czy istnieje sposób określenia, że ​​chcę, aby używał dowolnej wersji modułu w drzewie źródłowym? Myślałem, że ta sprawa zostanie załatwiona automatycznie. Nie chcę / nie sądzę, aby Maven wymagał budowania-instalacji-budowy-instalacji-kompilacji za każdym razem, gdy chcę po prostu stworzyć cały projekt!
Steven Schlansker
38
Masz rację, że uruchomienie instalacji rozwiązuje problem. Jednak teraz muszę instalować za każdym razem, gdy wprowadzam zmiany, co nie jest tym, czego chcę. Chcę, aby projekt magazynu pobierał najnowszy kod z projektu wspólnego.
Steven Schlansker
Właściwie mam do czynienia z podobnymi problemami i niestety - na razie nie jestem w stanie znaleźć odpowiedzi. Wygląda na to, że Maven nie przejmuje się tym, że zależność jest powiązana z twoim modułem, który po prostu natychmiast przechodzi do repozytorium. Dodam ulubione do twojego pytania - więc może jakiś guru odpowie. Jestem zainteresowany, aby dowiedzieć się, czy można to zrobić
Bostone
@Steven Napisz swoje obawy jako kolejne pytanie, nie warto odpowiadać w komentarzu, a to jest inny temat.
Pascal Thivent
6
To miało być główne pytanie, po prostu wyjaśniłem. Czy nie wyjaśniłem w pierwotnym pytaniu, że moim zamiarem jest nie wymaganie, aby zbudowane produkty znajdowały się w lokalnym repozytorium w celu zbudowania innych modułów w tym samym projekcie?
Steven Schlansker
104

Jak omówiono w tym wątku z listą dyskusyjną Mavena , cel zależność: drzewo sam z siebie będzie szukał rzeczy w repozytorium, a nie w reaktorze. Możesz obejść ten problem, instalując mvn, jak wcześniej sugerowano, lub robiąc coś mniej uciążliwego, co wywołuje reaktor, na przykład

mvn compile dependency:tree

Pracuje dla mnie.

Don Willis
źródło
2
Dziękujemy za to tanie obejście. Ale czy to błąd? Oczekuję zależności: cel drzewa zależy od reaktora bez żadnej sztuczki.
mcoolive,
Należy zauważyć, że ta sama sytuacja ma miejsce w przypadku każdego zadania wykonywanego globalnie, ale dotyczy tylko niektórych podprojektów.
tkruse
Niestety, compileuruchamia pobieranie zależności przechodnich. Czy jest też sposób na wyświetlenie drzewa zależności bez ich pobierania (z wyjątkiem oczywiście POM)?
sschuberth
Miałem ten sam problem w przypadku innych celów. Dodanie compile( validatenie wystarczy) również tam pomogło: mvn compile animal-sniffer:checkimvn compile org.basepom.maven:duplicate-finder-maven-plugin:check
msa
W zależności od kompilacji niektóre moduły mogą również mieć zależności od artefaktów, które są budowane w późniejszych fazach. W moim przypadku plik ZIP (używając wtyczki maven-assembly-plugin) był budowany w packagefazie, więc musiałem zrobić np mvn package animal-sniffer:check.
msa
6

Uświadomienie sobie, że jest to starszy wątek, ale wydaje się, że narzędzie ewoluowało lub mogło zostać pominięte za pierwszym razem.

Możliwe jest wykonanie kompilacji, która rozwiązuje zależności bez instalacji, wykonując kompilację reaktora.

Jeśli rozpoczniesz kompilację w module nadrzędnym, który opisuje strukturę modułów projektu, wówczas zależności między modułami zostaną rozwiązane podczas samej kompilacji za pośrednictwem wewnętrznego reaktora Maven.

Oczywiście nie jest to idealne rozwiązanie, ponieważ nie rozwiązuje problemu budowy pojedynczego indywidualnego modułu w strukturze. W tym przypadku Maven nie będzie miał zależności w swoim reaktorze i będzie szukał rozwiązania tego problemu w repozytorium. Tak więc w przypadku indywidualnych kompilacji nadal musisz najpierw zainstalować zależności.

Oto odniesienie opisujące tę sytuację.

Newtopian
źródło
1
Czy istnieje sposób na zbudowanie pojedynczego modułu bez wcześniejszego instalowania zależności i bez budowania całego projektu nadrzędnego?
WYJŚCIE - Anony-Mousse
1
Aby uzupełnić odpowiedź - jeśli wtyczka jest wywoływana bezpośrednio (bez faz), np mvn dependency:tree. Nadal nie rozwiąże zależności ze źródeł, chyba że wywołasz compilefazę. Więc to będzie działać zamiast: mvn compile dependency:tree.
Stanislav Bashkyrtsev
3

dla mnie to, co doprowadziło mnie do tego wątku, to podobny problem, a rozwiązaniem było upewnienie się, że wszystkie pom's zależności modułów mają

 <packaging>pom</packaging>

rodzic miał

pom

mój model dep miał pom - więc nie było słoika do znalezienia.

bsautner
źródło
To generuje dla mnie ten błąd: Błąd analizy odczytu POM. Powód: Nierozpoznany tag: „opakowanie”
powstało
edycja: miałem na myśli <packaging> pom </packaging>, naprawiłem to. wymiana <packaging> jar </packaging>
bsautner
4
To rozwiązuje problem opisany w pytaniu, ale teraz moduły potomne nie tworzą archiwów do eksportu (np. Słoiki, wojny, uszy).
sheldonh
sheldonh, czy znalazłeś rozwiązanie, aby naprawić ten błąd i utworzyć archiwum, które można wyeksportować?
user3853134
3

Jedyne, co mi zadziałało: przejście na gradle :(

mam

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

i mogę po prostu cd w war1 i użyć mvn tomcat7: run-war. Zawsze muszę instalować cały projekt wcześniej, mimo że war1 odwołuje się do jego rodzica, a rodzic odwołuje się do war1 i dep1 (jako modułów), więc wszystkie zależności powinny być znane.

Nie rozumiem, na czym polega problem.

mba
źródło
1
Dlatego używam gradle, gdy muszę stworzyć projekt wielomodułowy. :(
Zhuo YING
2

W strukturze modułu Maven, takiej jak ta:

- parent
  - child1
  - child2

Będziesz mieć w parent pomtym:

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

Jeśli teraz zależą child1w child2umieszczając następuje w <dependencies>IN child2:

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

Pojawi się błąd, którego child1nie można znaleźć pliku JAR . Można to rozwiązać, deklarując <dependencyManagement>blok zawierający child1w pomfor parent:

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

child1będzie teraz budować podczas uruchamiania compilelub packageitp gola na parent, i child2znajdzie child1„s skompilowanych plików.

obie lub
źródło
2

Dodatkowa odpowiedź od Dona Willisa :

Jeśli twoja kompilacja tworzy słoiki testowe do udostępniania kodu testowego między podmodułami reaktora, powinieneś użyć:

mvn test-compile dependency:tree

co pozwoli dependency:treew tym przypadku działać do końca.

adrock20
źródło
-1

Upewnij się, że moduł, który uległ awarii, zostanie rozwiązany w pomie, wskazuje właściwego rodzica, włączając konfiguracje do pliku pom modułu.

Nitin Kamate
źródło