Wydaje się, że istnieje kilka sposobów na zbudowanie poms nadrzędnych w kompilacji z wieloma projektami i zastanawiam się, czy ktoś miał jakieś przemyślenia na temat zalet / wad każdego z nich.
Najprostszą metodą posiadania rodzica pom byłoby umieszczenie go w katalogu głównym projektu, tj
myproject/
myproject-core/
myproject-api/
myproject-app/
pom.xml
gdzie pom.xml jest zarówno projektem nadrzędnym, jak i opisuje moduły -core -api i -app
Następną metodą jest oddzielenie elementu nadrzędnego do własnego podkatalogu, jak w
myproject/
mypoject-parent/
pom.xml
myproject-core/
myproject-api/
myproject-app/
Gdzie pom pom nadal zawiera moduły, ale są względne, np. ../Myproject-core
Wreszcie istnieje opcja, w której definicja modułu i element nadrzędny są oddzielone jak w
myproject/
mypoject-parent/
pom.xml
myproject-core/
myproject-api/
myproject-app/
pom.xml
Gdzie pom nadrzędny zawiera dowolną konfigurację „współdzieloną” (dependenceManagement, właściwości itp.), A plik myproject / pom.xml zawiera listę modułów.
Zamiarem jest skalowalność do kompilacji na dużą skalę, dlatego powinna być skalowalna do dużej liczby projektów i artefaktów.
Kilka dodatkowych pytań:
- Gdzie jest najlepsze miejsce do zdefiniowania różnych wspólnych konfiguracji, takich jak kontrola źródła, katalogi wdrażania, wspólne wtyczki itp. (Zakładam, że nadrzędny, ale często mnie to gryzie i kończą w każdym projekcie, a nie w każdym projekcie wspólny).
- W jaki sposób wtyczka maven-release, Hudson i Nexus radzą sobie z konfiguracją wielu projektów (być może gigantyczne pytanie, to bardziej, jeśli ktoś został przyłapany na tym, jak skonfigurowano kompilację wielu projektów)?
Edycja: Każdy z podprojektów ma swój własny plik pom.xml, pominąłem go, aby był zwięzły.
źródło
Odpowiedzi:
Moim zdaniem, aby odpowiedzieć na to pytanie, należy pomyśleć o cyklu życia projektu i kontroli wersji. Innymi słowy, czy pom rodzicielski ma swój własny cykl życia, tj. Czy można go wypuścić oddzielnie od innych modułów, czy nie?
Jeśli odpowiedź brzmi tak (i tak jest w przypadku większości projektów, które zostały wspomniane w pytaniu lub w komentarzach), to pom rodzicielski potrzebuje własnego modułu z VCS i z punktu widzenia Maven, a skończysz z czymś takim na poziomie VCS:
To sprawia, że kasa jest nieco bolesna i powszechnym sposobem radzenia sobie z tym jest użycie
svn:externals
. Na przykład dodajtrunks
katalog:Z następującą definicją czynników zewnętrznych:
Wyewidencjonowanie
trunks
skutkowałoby wówczas następującą strukturą lokalną (wzór nr 2):Opcjonalnie możesz nawet dodać
pom.xml
wtrunks
katalogu:Jest
pom.xml
to rodzaj „fałszywego” pomu: nigdy nie został wydany, nie zawiera prawdziwej wersji, ponieważ ten plik nigdy nie został wydany, zawiera tylko listę modułów. W przypadku tego pliku kasa spowodowałaby następującą strukturę (wzór nr 3):Ten „hack” umożliwia uruchomienie kompilacji reaktora od korzenia po kasie i sprawia, że rzeczy są jeszcze bardziej przydatne. Tak właśnie lubię konfigurować projekty maven i repozytorium VCS dla dużych kompilacji : po prostu działa, dobrze się skaluje, daje całą elastyczność, jakiej możesz potrzebować.
Jeśli odpowiedź brzmi „ nie” (wróć do pierwotnego pytania), to myślę, że możesz żyć według wzoru nr 1 (zrób najprostszą rzecz, która może działać).
Teraz na temat dodatkowych pytań:
Szczerze mówiąc, nie wiem, jak nie udzielić tutaj ogólnej odpowiedzi (np. „Użyj poziomu, na którym Twoim zdaniem sensowne jest mutualizowanie rzeczy”). W każdym razie poms dzieci zawsze mogą zastąpić odziedziczone ustawienia.
Konfiguracja, której używam, działa dobrze, nie wspominając o niczym szczególnym.
Właściwie zastanawiam się, jak wtyczka maven-release-plugin radzi sobie ze wzorem nr 1 (szczególnie z tą
<parent>
sekcją, ponieważ nie można mieć zależności SNAPSHOT w czasie wydania). To brzmi jak problem z kurczakiem lub jajkiem, ale po prostu nie pamiętam, czy działa i był zbyt leniwy, aby go przetestować.źródło
Z mojego doświadczenia i najlepszych praktyk Maven są dwa rodzaje „poms” dla rodziców
„firma” nadrzędna pom - ta pom zawiera informacje i konfigurację specyficzne dla twojej firmy, które dziedziczą każdą pompę i nie trzeba jej kopiować. Te informacje to:
Przygotowywanie tego pom-pom musi być wykonane ostrożnie, ponieważ wszystkie poms w twojej firmie odziedziczą po nim, więc ten pom musi być dojrzały i stabilny (wydanie wersji pom-pom nie powinno wpłynąć na uwolnienie wszystkich projektów twojej firmy!)
Mutliprojects mają strukturę drzew - więc nie jesteś przyzwyczajony do jednego poziomu pom-rodzica. Spróbuj znaleźć odpowiednią strukturę projektu dla swoich potrzeb - klasyczny przykład to, jak rozbić projekty wielomodułowe
Tę konfigurację należy mądrze rozdzielić na „pom” nadrzędne „pom” i nadrzędne „pom” nad projektem. Rzeczy związane ze wszystkim, co projektują, trafiają do rodzica „firmy”, a to związane z bieżącym projektem przechodzi do projektu własnego.
Najpierw należy wypuścić macierzystą spółkę. W przypadku wielu projektów obowiązują standardowe zasady. Serwer CI musi wiedzieć wszystko, aby poprawnie zbudować projekt.
źródło
Niezależny element nadrzędny to najlepsza praktyka do udostępniania konfiguracji i opcji między niepołączonymi komponentami. Apache ma nadrzędny projekt pom, który udostępnia informacje prawne i niektóre typowe opcje pakowania.
Jeśli twój projekt najwyższego poziomu ma w sobie prawdziwą pracę, taką jak agregacja javadoc lub pakowanie wydania, będziesz mieć konflikty między ustawieniami potrzebnymi do wykonania tej pracy a ustawieniami, które chcesz udostępnić przez rodzica. Projekt tylko dla rodziców unika tego.
Powszechnym wzorcem (na razie ignorując # 1) jest to, że projekty z kodem używają projektu nadrzędnego jako nadrzędnego i używają najwyższego poziomu jako nadrzędnego. Pozwala to wszystkim dzielić się podstawowymi rzeczami, ale pozwala uniknąć problemu opisanego w punkcie 2.
Wtyczka witryny będzie bardzo zdezorientowana, jeśli struktura nadrzędna nie będzie taka sama jak struktura katalogów. Jeśli chcesz zbudować zagregowaną witrynę, musisz zrobić trochę majstrowania, aby obejść ten problem.
Apache CXF jest przykładem wzorca z # 2.
źródło
W trzecim podejściu jest jeden mały haczyk. Ponieważ agregowane POM (myproject / pom.xml) zwykle nie mają w ogóle elementu nadrzędnego, nie współużytkują konfiguracji. Oznacza to, że wszystkie te POM będą mieć tylko domyślne repozytoria.
Nie stanowi to problemu, jeśli korzystasz tylko z wtyczek z centralnej wersji, ale to się nie powiedzie, jeśli uruchomisz wtyczkę przy użyciu formatu wtyczki: cel z wewnętrznego repozytorium. Na przykład możesz mieć
foo-maven-plugin
parametr groupIdorg.example
zapewniający celgenerate-foo
. Jeśli spróbujesz uruchomić go z katalogu głównego projektu za pomocą polecenia podobnegomvn org.example:foo-maven-plugin:generate-foo
, nie będzie działać na modułach agregujących (patrz uwaga dotycząca zgodności ).Możliwych jest kilka rozwiązań:
źródło