Bağımlılık ve Maven'deki bağımlılıklar arasındaki farklar


766

Arasındaki fark nedir dependencyManagementve dependencies? Apache Maven web sitesinde belgeleri gördüm. Görünüşe göre, altında tanımlanan bir bağımlılık dependencyManagementalt modüllerinde kullanılabilir.

Örneğin:

Bir üst proje (Pro-par) aşağıdakiler altında bir bağımlılık tanımlar dependencyManagement:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8</version>
    </dependency>
 </dependencies>
</dependencyManagement>

Sonra Pro-par'ın çocuğunda, juniti kullanabilirim:

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    </dependency>
 </dependencies>

Ancak, ebeveyn pom'da junit tanımlamanın gerekli olup olmadığını merak ediyorum? Neden doğrudan gerekli modülde tanımlamıyorsunuz?

Yanıtlar:


463

Bağımlılık Yönetimi , bağımlılık sürümlerinin yönetimini tüm çocuklar tarafından miras alınan bağımlılıklar eklemeden birleştirmeye ve merkezileştirmeye izin verir. Bu, özellikle ortak bir ebeveyni devralan bir dizi projeniz (yani birden fazla) olduğunda kullanışlıdır .

Bir diğer son derece önemli kullanım örneği, dependencyManagementgeçişli bağımlılıklarda kullanılan eserlerin sürümlerinin kontrol edilmesidir. Bunu örnek olmadan açıklamak zor. Neyse ki, bu belgelerde gösterilmiştir.


17
Peki, <dependencyManagement> bölümünde ana projenin pom'ında beyan etseler bile, çocuk projesi pom'larında bağımlılıkları beyan etme ihtiyacı var mı? Bağımlılıkların bir çeşit mirasını yapmak mümkün mü?
johnny-b-goode

55
Evet, onları kullandığınızı göstermek için hala çocuk POM'sinde tanımlamanız gerekir. Sadece <dependencyManagement>ana POM'da oldukları için çocuk projelerine dahil edilmezler . Kullanmaya <dependencyManagement>karar verirseniz, kullanmaya karar verirseniz, her bağımlılık için sürüm, kapsam ve hariç tutulanların yönetimini merkezileştiren bağımlılıklar. Maven'in bağımlılık yönetimi kılavuzu tüm ayrıntıları ele alıyor.
hotshot309

2
İkinci paragraf ( dependencyManagementgeçişli bağımlılıkları da kontrol eder) yalnızca bağımlılıklar açıkça ayarlandığında doğrudur: stackoverflow.com/questions/28312975/…
Robert Metzger

2
@ johnny-b-goode Hala yapabileceğiniz şey dependenciesana pompanızda yeni bir bölüm oluşturmaktır . Bunu, tüm çocuk projelerinin varsayılan olarak bazı apache-ortaklarına sahip olmasını ve her zaman ilan etmemesini sağladık.
рüффп

771

Bu soruya şık bir şekilde geç kaldım, ancak kabul edilenlerden daha net bir yanıt vermeye değer olduğunu düşünüyorum (bu doğru, ancak kendinizi çıkarmanız gereken gerçek önemli kısmı vurgulamıyor).

Ana POM'da <dependencies>ve arasındaki ana fark <dependencyManagement>şudur:

<dependencies>Bölümde belirtilen yapay nesneler DAİMA alt modül (ler) in bağımlılığı olarak dahil edilecektir.

<dependencyManagement>Bölümde belirtilen yapay nesneler , yalnızca <dependencies>alt modülün kendisinde de belirtildiyse, alt modüle dahil edilecektir . Sormak neden iyi? çünkü üst öğede sürümü ve / veya kapsamı belirtirsiniz ve alt POM içindeki bağımlılıkları belirlerken bunları dışlayabilirsiniz. Bu, her alt modüldeki sürümü belirtmeden alt modüller için bağımlılıklar için birleştirilmiş sürümler kullanmanıza yardımcı olabilir.


1
Ama aynı zamanda kök <dependencyManagement>üzerinde biraz yükü değil mi? Çocuk çok daha kısa olabilir. <dependencies>.pompom
Janez Kuhar

18
Bu doğru. <dependencyManagement> yerine <bağımlılıklar> kullanılması daha kısa bir çocuk pompası oluşturur. Bununla birlikte, bir maliyetle gelir - bu bağımlılıkların HER ZAMAN tüm alt modüller için HER ZAMAN tanımlanacağı anlamına gelir. Alt modüllerin yalnızca BAZI belirli bir bağımlılığa ihtiyaç duyuyorsa, bunun yerine "<dependencyManagement>" kullanmaktan ziyade hangi alt modüllerin bu bağımlılığa sahip olacağını seçmenize ve bağımlılık sürümünü yalnızca ana pom'da ayarlayarak yine de biraz verimli olmanıza izin verir.
dcoder

2
@JanezKuhar Alt modülde bir bağımlılık belirtirseniz, üst öğedekini geçersiz kılacağını hatırlıyorum, ama hatırlamıyorum. Şansım olduğunda, bunun için maven belgelerini kontrol etmem gerekecek. Basit bir ebeveyn-çocuk projesi
kurmak

26
Basit bir kavram için iyi bir açıklama - Maven'in kendi araçlarını bu kadar kolay açıklamak neden bu kadar zor görünüyor?
jimmy_terra

1
Ben Artifacts specified in the <dependencies> section will ALWAYS be included as a dependency of the child module(s)de ebeveyn dahil olduğunu eklemek istiyorum . Çocuklar için bir bağımlılık kurmak mümkün görünmüyor, ancak ebeveyn için değil.
caduceus

54

Dokümantasyon Maven sitesinde korkunç. Yönetimin bağımlılığı, bağımlılık tanımlarınızı (sürüm, istisnalar, vb.) Ana pompayı yukarı taşımaktır, o zaman çocuk pomplarına groupId ve artifactId'yi koymanız yeterlidir. Bu kadar (ebeveyn pom zinciri ve benzerleri hariç, ama bu da gerçekten karmaşık değil - bağımlılıkYönetim üst düzeydeki bağımlılıkları kazanır - ancak bu veya ithalatla ilgili bir sorunuz varsa Maven belgeleri biraz daha iyidir).

Maven bölgesindeki tüm 'a', 'b', 'c' çöplerini okuduktan ve karıştıktan sonra örneklerini yeniden yazdım. Dolayısıyla, ortak bir bağımlılığı (betaShared) paylaşan 2 projeniz (proj1 ve proj2) varsa, bu bağımlılığı ana pom'a taşıyabilirsiniz. Siz oradayken, ancak projeniz için mantıklıysa, diğer bağımlılıkları da (alfa ve charlie) yükseltebilirsiniz. Dolayısıyla, önceki cümlelerde ana hatları verilen durum için, bağımlılığa sahip çözüm İşte ana pom'da yönetim:

<!-- ParentProj pom -->
<project>
  <dependencyManagement>
    <dependencies>
      <dependency> <!-- not much benefit defining alpha here, as we only use in 1 child, so optional -->
        <groupId>alpha</groupId>
        <artifactId>alpha</artifactId>
        <version>1.0</version>
        <exclusions>
          <exclusion>
            <groupId>zebra</groupId>
            <artifactId>zebra</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
      <dependency>
        <groupId>charlie</groupId> <!-- not much benefit defining charlie here, so optional -->
        <artifactId>charlie</artifactId>
        <version>1.0</version>
        <type>war</type>
        <scope>runtime</scope>
      </dependency>
      <dependency> <!-- defining betaShared here makes a lot of sense -->
        <groupId>betaShared</groupId>
        <artifactId>betaShared</artifactId>
        <version>1.0</version>
        <type>bar</type>
        <scope>runtime</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

<!-- Child Proj1 pom -->
<project>
  <dependencies>
    <dependency>
      <groupId>alpha</groupId>
      <artifactId>alpha</artifactId>  <!-- jar type IS DEFAULT, so no need to specify in child projects -->
    </dependency>
    <dependency>
      <groupId>betaShared</groupId>
      <artifactId>betaShared</artifactId>
      <type>bar</type> <!-- This is not a jar dependency, so we must specify type. -->
    </dependency>
  </dependencies>
</project>

<!-- Child Proj2 -->
<project>
  <dependencies>
    <dependency>
      <groupId>charlie</groupId>
      <artifactId>charlie</artifactId>
      <type>war</type> <!-- This is not a jar dependency, so we must specify type. -->
    </dependency>
    <dependency>
      <groupId>betaShared</groupId> 
      <artifactId>betaShared</artifactId> 
      <type>bar</type> <!-- This is not a jar dependency, so we must specify type. -->
    </dependency>
  </dependencies>
</project>

2
Biraz konu dışı soru: bağımlılık türü "bar" ne anlama geliyor? Maven belgelerinde örnek bir pom gördüm ama bir tanım bulamadım. Bunun "savaş" veya "kavanoz" yazım hatası olduğunu varsaydım, ama bunu seninki gibi diğer örneklerde görüyorum.
Kimse

Kimse - Bu sadece başka bir arşiv türü için bir yer tutucudur. 'Foo' kullanmak gibi. Veya birisi 'bar' uzantısıyla özel bir tür oluşturduysa kullanılabilir. Ve orada çok sayıda gizli arşiv türü var. Jboss servis arşivi olan sar gibi.
MattC

Örneğiniz oldukça açık ve dokümantasyondan kendi başıma attığımı teyit ediyor. Maven projesine gönderdiniz mi? Örneğinizi inceledikten sonra, ilişkili olduğu projenin çocuğu olmadığı için her ikisine de sahip olan ve yalnızca Bağımlılık bildirimlerine ihtiyaç duyan bir POM'u basitleştirmeye hazırlıyorum.
David

Eh, DependencyManagement düğümünü bırakmak üzereydim, bana bırakana kadar, bağımlılık ağacına dolaylı olarak yol bulan çocuk POM'ları için minimum bir sürüm oluşturmama izin verdi. Örnek olarak, javax.cache.cache-apI'yi takip ederken, baştan sona kullanılabilecek önemli ölçüde daha yeni bir sürüm 1.0.0 (0.3.0'a karşı) keşfettim.
David

Bu açıklama pefect.
Akıllı Kodlayıcı

45

Söylediğin gibi; dependencyManagementtüm bağımlılık bilgilerini ortak bir POM dosyasına çekmek ve alt POM dosyasındaki referansları basitleştirmek için kullanılır.

Birden çok alt projede yeniden yazmak istemediğiniz birden çok özelliğiniz olduğunda yararlı olur.

Son olarak, dependencyManagementbirden fazla projede kullanılacak bir yapının standart bir versiyonunu tanımlamak için kullanılabilir.


4
Yani, bağımlılıklar kalıtsal değil mi? Yine de çocuk projesinin pom'da ilan edilmesi gerekiyor mu?
johnny-b-goode

6
Evet, çocuk projelerinde onları bir sürüm belirtmeden beyan etmelisiniz.
Pavel Vlasov

Bu senaryo, üst-alt ilişkisi olan birden fazla java projesinde sürümlerin yönetilmesini istediğinizde kullanışlıdır.
Anuj Kumar

43

Bana göre yeterince vurgulanmayan ve istenmeyen miras olan bir şey var .

İşte artımlı bir örnek:

parentPommda beyan ederim :

<dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>19.0</version>
        </dependency>
</dependencies>

Boom! Benim içinde var Child A, Child Bve Child Cmodüllerin:

  • Çocuk pomları tarafından miras alınan imtiyaz
  • Yönetmek için tek bir yer
  • Çocuk pompasında herhangi bir şeyi yeniden bildirmeye gerek yok
  • Hala redelcare ve geçersiz kılma yapabilirsiniz version 18.0bir de Child Bben istiyorum.

Ama içinde guava gerektirmiyor ne sonunda eğer Child Cve ne gelecekte Child Dve Child Emodüllerin?

Hala miras alacaklar ve bu istenmeyen bir durum! Bu, tıpkı bir sınıftan bazı yararlı bitleri ve bir ton istenmeyen şeyi miras aldığınız Java God Object kod kokusuna benzer.

İşte burada <dependencyManagement>devreye giriyor. Bunu ana pompanıza eklediğinizde, tüm alt modülleriniz görmeyi DURDUR . Ve böylece ihtiyacınız olan her bir modüle girmek zorunda kalırsınız ve tekrar beyan edersiniz ( Child Ave Child Bversiyon olmadan).

Ve tabii ki, bunu Child Csizin için yapmazsınız ve böylece modülünüz zayıf kalır.


<dependencyManagement> 'de belirtilen bağımlılıklar ana pom projesi için indirilecek mi?
Jaspreet Jolly

<dependencyManagement>Ebeveyn pom'da kullanırsak , varsayılan olarak bağımlılıkların çocuk pomslarına miras alınmayacağından emin misiniz? Çünkü dokümanda: maven.apache.org/guides/introduction/… ikinci kullanımını açıklarken <dependencyManagement>varsayılan olarak devralınacak gibi görünüyor. Bir satırda şöyle diyorlar: "maven, B projesi üzerinde çalıştırıldığında, a, b, c ve d eserlerinin 1.0 sürümü," b ", B projesi
chirag soni

Kendiniz deneyin
Andrejs

17

Maven ile etiketler arasındaki farkları <depedencies>ve <dependencyManagement>etiketleri özetleyen birkaç cevap vardır .

Bununla birlikte, aşağıda birkaç nokta kısa bir şekilde detaylandırılmıştır:

  1. <dependencyManagement>farklı modüllerde kullanılan tüm bağımlılıkları (çocuk pom seviyesinde kullanılır) birleştirmeye izin verir - açıklık , merkezi bağımlılık sürüm yönetimi
  2. <dependencyManagement>ihtiyaca göre bağımlılıkların kolayca yükseltilmesine / düşürülmesine izin verir, diğer senaryoda bunun her çocuk pom seviyesinde uygulanması gerekir - tutarlılık
  3. <dependencies>etikette sağlanan bağımlılıklar her zaman içe aktarılırken, <dependencyManagement>ana pom'da sağlanan bağımlılıklar yalnızca alt pom'un <dependencies>etiketine ilgili girişi varsa içe aktarılır .

17

Üzgünüm partiye çok geç kaldım.

mvn dependency:treeKomut kullanarak farkı açıklamaya çalışayım

Aşağıdaki örneği düşünün

Veli POM - Projem

<modules>
    <module>app</module>
    <module>data</module>
</modules>

<dependencies>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>19.0</version>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
    </dependencies>
</dependencyManagement>

Alt POM - veri modülü

<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
    </dependency>
</dependencies>

Alt POM - uygulama modülü (ekstra bağımlılığı yoktur, bu nedenle bağımlılıkları boş bırakır)

 <dependencies>
</dependencies>

Çalıştırırken mvn dependency:treeaşağıdaki sonucu alırız

Scanning for projects...
------------------------------------------------------------------------
Reactor Build Order:

MyProject
app
data

------------------------------------------------------------------------
Building MyProject 1.0-SNAPSHOT
------------------------------------------------------------------------

--- maven-dependency-plugin:2.8:tree (default-cli) @ MyProject ---
com.iamvickyav:MyProject:pom:1.0-SNAPSHOT
\- com.google.guava:guava:jar:19.0:compile

------------------------------------------------------------------------
Building app 1.0-SNAPSHOT
------------------------------------------------------------------------

--- maven-dependency-plugin:2.8:tree (default-cli) @ app ---
com.iamvickyav:app:jar:1.0-SNAPSHOT
\- com.google.guava:guava:jar:19.0:compile

------------------------------------------------------------------------
Building data 1.0-SNAPSHOT
------------------------------------------------------------------------

--- maven-dependency-plugin:2.8:tree (default-cli) @ data ---
com.iamvickyav:data:jar:1.0-SNAPSHOT
+- org.apache.commons:commons-lang3:jar:3.9:compile
\- com.google.guava:guava:jar:19.0:compile

Google guava , her modülde (üst öğe dahil) bağımlılık olarak listelenirken , apache ortak alanları yalnızca veri modülünde (üst modülde bile değil) bağımlılık olarak listelenir


11

Bağımlılık en üst düzey pom'un dependsencyManagement öğesinde tanımlandıysa, alt projenin bağımlılığın sürümünü açıkça listelemesi gerekmez. alt proje bir sürüm tanımladıysa, en üst düzey POM'un bağımlılık Yönetimi bölümünde listelenen sürümü geçersiz kılar. Yani, dependsencyManagement sürümü yalnızca alt öğe doğrudan bir sürüm bildirmediğinde kullanılır.


1
Bu ifadenin doğru olmayabileceğine inanıyorum. Maven'in Bağımlılık Yönetimi örneklerinde (# 2), bir sürüm içeren bir üst pom'da tanımlanan bağımlılıkların alt pom'da belirtilen sürümü geçersiz kılacağını söylüyorlar: "maven, a, b, c eserlerinin B proje 1.0 sürümünde çalıştırıldığında ve d pom'larında belirtilen sürümden bağımsız olarak kullanılacaktır. "
devdanke

@devdanke En azından Eclipse m2e bir uyarı veriyor: Yönetilen sürümü geçersiz kılmak ... için .
GeroldBroser Monica

4

Ana POM'da <dependencies>ve arasındaki ana fark <dependencyManagement>şudur:

<dependencies>Bölümde belirtilen yapay nesneler DAİMA alt modül (ler) in bağımlılığı olarak dahil edilecektir.

Bölümde belirtilen yapay nesneler, yalnızca alt modülün kendisinde de belirtildiyse, alt modüle dahil edilecektir. Sormak neden iyi? çünkü üst öğede sürümü ve / veya kapsamı belirtirsiniz ve alt POM içindeki bağımlılıkları belirlerken bunları dışlayabilirsiniz. Bu, her alt modüldeki sürümü belirtmeden alt modüller için bağımlılıklar için birleştirilmiş sürümler kullanmanıza yardımcı olabilir.


4

Sadece kendi sözlerimle, parent-project2 çeşit bağımlılık sağlamanıza yardımcı olur:

  • örtük bağımlılıklar : <dependencies>sizin bölümünüzde tanımlanan tüm bağımlılıklar parent-project,child-projects
  • açık bağımlılıklar : uygulamanız için bağımlılıkları seçmenize izin verir child-projects. Bu nedenle, <dependencyManagement>bölümünüzü, farklılarınızda kullanacağınız tüm bağımlılıkları beyan etmek için kullanırsınız child-projects. En önemli şey, bu bölümde, bir kez daha tanımlamak <version>zorunda kalmamanızdır child-project.

<dependencyManagement>Eğer bağımlılıkları sürümünü merkezileştirme yardımcı olarak sadece yararlıdır benim açımdan içinde (hatam varsa düzeltin). Bir çeşit yardımcı özellik gibidir.


1

Eclipse'de, 'de bir özellik daha var dependencyManagement. Ne zaman dependencieso olmadan kullanılırsa, hergün bağımlılıkları pom dosyasında fark edilir. Eğer dependencyManagementkullanılırsa, çözülmemiş bağımlılıkları pom dosyasında farkedilmeden kalır ve hatalar java dosyalarında sadece görünür. (ithalat ve benzeri ...)


1

İkisi arasındaki fark en iyi şekilde Maven web sitesi belgelerinde bulunan bağımlılık Yönetim öğesinin gerekli ve yeterli bir tanımını ortaya çıkarır:

dependencyManagement

Msgstr "Bu bölümden devralınan projeler için varsayılan bağımlılık bilgileri. Bu bölümdeki bağımlılıklar hemen çözümlenmez. Bunun yerine, bundan türetilen bir POM eşleşen groupId ve artifactId tarafından açıklanan bağımlılığı bildirirse, bu bölümdeki sürüm ve diğer değerler zaten belirtilmemişlerse bu bağımlılık için kullanılır. " [ https://maven.apache.org/ref/3.6.1/maven-model/maven.html ]

Farklı bir sayfada bulunan daha fazla bilgi ile birlikte okunmalıdır:

“.. bağımlılık referansını bir dependsencyManagement bölümü ile eşleştirmek için asgari bilgi kümesi aslında {groupId, artifactId, type, classifier} şeklindedir. Çoğu durumda, bu bağımlılıklar sınıflandırıcısız kavanoz eserlerine işaret eder. Bu, {groupId, artifactId} olarak ayarlanan kimliği kısaltmamıza izin verir, çünkü tür alanı için varsayılan jar ve varsayılan sınıflandırıcı boştur. ” [ https://maven.apache.org/guides/introduction/introduction-to- bağımlılığı-mekanizm.html ]

Bu nedenle, bağımlılık öğesinin tüm alt elemanları (kapsam, hariç tutmalar vb.) - groupId, artifactId, type, sınıflandırıcı, sadece sürüm değil - bu noktada kilitleme / varsayılan için kullanılabilir (ve dolayısıyla orada daha sonra) bir dependsityElement içindeki bağımlılığı belirtirsiniz. Tür ve sınıflandırıcı alt öğelerine bağımlılık belirlediyseniz (tüm alt öğelerin kontrol edilmesi için ilk belirtilen web sayfasına bakın) sırasıyla kavanoz değil boş olmalı, {groupId, artifactId, classifier, type} ve bu bağımlılığı, bağımlılık bağımlılık kaynağından kaynaklanan bir kalıtımdaki herhangi bir noktaya gönderme (çözme). Sınıflandırıcı ve tür (sırasıyla jar ve null) için varsayılanları geçersiz kılmak istemiyorsanız, başka, {groupId, artifactId} yeterli olacaktır. Yani varsayılan, bu tanımda iyi bir anahtar kelimedir; herhangi bir alt eleman (lar) (groupId dışında,

Bu nedenle, dependsmManagement dışındaki herhangi bir bağımlılık öğesi, ister bir bağımlılıkYönetim öğesine bir referans olarak ister bağımsız olarak hemen çözülür (yani, yerel veri havuzuna kurulur ve sınıfyolları için kullanılabilir).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.