Bir ana POM'dan devralınan eserleri hariç tutmak için yine de var mı?


120

Bağımlılıklardan gelen yapılar, bir <exclusions>öğe içinde bir öğe bildirilerek hariç tutulabilir. <dependency>Ancak bu durumda, bir üst projeden miras alınan bir yapıyı dışlamak gerekir. Tartışılan POM'dan bir alıntı aşağıdaki gibidir:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>test</groupId>
  <artifactId>jruby</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <parent>
        <artifactId>base</artifactId>
        <groupId>es.uniovi.innova</groupId>
        <version>1.0.0</version>
    </parent>

    <dependencies>      
        <dependency>
            <groupId>com.liferay.portal</groupId>
            <artifactId>ALL-DEPS</artifactId>
            <version>1.0</version>
            <scope>provided</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</project>

baseyapı aynı kitaplığın başka bir sürümüne bağlıdır javax.mail:mail-1.4.jarve ALL-DEPSbağlıdır. Ticari kullanımda mail.jargelen ALL-DEPSile çarpışır dışa değil, ancak işletme ortamı biri, mail.jarşekilde odaklanan ebeveyn bulunduğunucompile .

Bir çözüm mail.jar dosyasını ana POM'dan çıkarmak olabilir, ancak tabanı devralan projelerin çoğu buna ihtiyaç duyar (log4j için geçici bir bağımlılık olduğu gibi). Bu yüzden yapmak istediğim şey, ebeveynin kütüphanesini alt projeden çıkarmaktır , çünkü bu basebir bağımlılık olsaydı ve ebeveyn pom değil ise yapılabilirdi :

...
    <dependency>
        <artifactId>base</artifactId>
        <groupId>es.uniovi.innova</groupId>
        <version>1.0.0</version>
        <type>pom<type>
        <exclusions>
          <exclusion>
             <groupId>javax.mail</groupId>
             <artifactId>mail</artifactId>
          </exclusion>
        </exclusions>
    </dependency>
...

Yanıtlar:


49

Bazı fikirler:

  1. Belki bu durumda ebeveynden miras alamazsınız (ve basedışlama ile bir bağımlılık beyan edemezsiniz ). Ebeveyn ponponunda çok şey varsa kullanışlı değil.

  2. Testine başka şey ilan etmek olacağını mailgerektirdiği sürümü ile objeyi ALL-DEPSaltında dependencyManagement(Eminim bu kapsam sorunu çözecektir değilim rağmen) yakınlaşma zorlamak için üst pom içinde.

<dependencyManagement>
  <dependencies>
    <dependency>    
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
      <version>???</version><!-- put the "right" version here -->
    </dependency>
  </dependencies>
</dependencyManagement>
  1. Ya da mailbağımlılığı log4j'den hariç tutabilirsiniz, eğer ona dayanan özellikleri kullanmıyorsanız (ve ben de bunu yapardım):
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.15</version>
  <scope>provided</scope>
  <exclusions>
    <exclusion>
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
    </exclusion>
    <exclusion>
      <groupId>javax.jms</groupId>
      <artifactId>jms</artifactId>
    </exclusion>
    <exclusion>
      <groupId>com.sun.jdmk</groupId>
      <artifactId>jmxtools</artifactId>
    </exclusion>
    <exclusion>
      <groupId>com.sun.jmx</groupId>
      <artifactId>jmxri</artifactId>
    </exclusion>
  </exclusions>
</dependency>
  1. Ya da sapkın 1.2.15 sürümü yerine log4j'nin 1.2.14 sürümüne geri dönebilirsiniz (neden yukarıdaki bağımlılıkları isteğe bağlı olarak işaretlemediler?! ).

Cevabın için teşekkürler. Çok sayıda yararlı bilgi içerir. 1) Sizin de fark ettiğiniz gibi optimal olmayacaktır çünkü ebeveyn pom sadece temel bağımlılık olarak işaretlendiğinde geçişli olarak çözülecek bağımlılıkları değil, aynı zamanda ortak raporlama, kaynak yönetimi ve şirketteki her proje arasında yeniden kullanılan diğer şeyleri de içerir. 2) ile ilgili olarak denedim, ama aynı zamanda sunulmuş olan yapının kapsamını belirledim ve işe yaradı :). İlk başta, derlemenin sağlanandan öncelikli olduğunu düşündüm, ancak neyse ki yanılmışım (çocuk POM, ebeveynin yapılandırmasını geçersiz kılar)
Miguel

29

Bağımlılıklarınızı farklı bir proje içinde pom, Sonatypes Best Practices tarafından açıklandığı gibi paketleme ile gruplayabilirsiniz :

<project>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>base-dependencies</artifactId>
    <groupId>es.uniovi.innova</groupId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    <dependencies>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4</version>
        </dependency>
    </dependencies>
</project>

ve onlara ebeveyn-pom'unuzdan referans verin (bağımlılığı izleyin <type>pom</type>):

<project>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>base</artifactId>
    <groupId>es.uniovi.innova</groupId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    <dependencies>
        <dependency>
            <artifactId>base-dependencies</artifactId>
            <groupId>es.uniovi.innova</groupId>
            <version>1.0.0</version>
            <type>pom</type>
        </dependency>
    </dependencies>
</project>

Çocuk projeniz daha önce olduğu gibi bu ebeveyn-pomu devralır. Ancak artık posta bağımlılığı dependencyManagementblok içindeki alt projede hariç tutulabilir :

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>test</groupId>
    <artifactId>jruby</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <parent>
        <artifactId>base</artifactId>
        <groupId>es.uniovi.innova</groupId>
        <version>1.0.0</version>
    </parent>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <artifactId>base-dependencies</artifactId>
                <groupId>es.uniovi.innova</groupId>
                <version>1.0.0</version>
                <exclusions>
                    <exclusion>
                        <groupId>javax.mail</groupId>
                        <artifactId>mail</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

4
Bunun için +1, ancak alt pom <dependencyManagement> yerine <dependency> bölümünü kullanmalıdır, çünkü ikincisi bağımlılık sürümlerini bir ebeveyn pom içinden yönetmek içindir .
Matthew Wise

1
Bu aynı zamanda ürün reçetesi olarak da bilinir, namı diğer malzeme listesi :-)
Pim Hazebroek

Bu yalnızca geçişli bağımlılıklarla mı çalışır? Ebeveyn pomum log4j içeriyor ve bu, pom'umun oturum açmasının düzgün çalışmasını engelliyor.
Sridhar Sarnobat

10

Bir ebeveyn pom kullanma

Bu kulağa aşırı gelebilir, ancak aynı şekilde "kalıtım cehennemi", bazı kişilerin Nesne Yönelimli Programlamaya sırtlarını dönmelerinin (veya kalıtım yerine kompozisyonu tercih etmelerinin ), sorunlu <parent>bloğu kaldırmanın ve ihtiyacınız olan her şeyi kopyalayıp yapıştırmanın bir nedenidir <dependencies>(ekibiniz size verirse) bu özgürlük).

Pomların "yeniden kullanım" ve "fazlalıktan kaçınma" için ebeveyn ve çocuğa bölünmesi varsayımı göz ardı edilmeli ve ilk önce acil ihtiyaçlarınızı karşılamalısınız (tedavi hastalıktan daha kötüdür). Ayrıca, fazlalığın avantajları vardır - yani dış değişikliklerden bağımsızlık (yani istikrar).

Etkili bir pom üretirseniz, bu göründüğünden daha kolaydır (tutulma sağlar ancak komut satırından oluşturabilirsiniz mvn help:effective).

Misal

logbackSlf4j bağlamam olarak kullanmak istiyorum , ancak ebeveyn pom'um log4jbağımlılığı içeriyor . Gitmek istemiyorum ve diğer çocukların log4j'ye bağımlılığını kendi pom.xmldosyalarına itmek zorunda kaldım ki benimki engellenmesin.


1
Bunu (ve uyguladığınız prosedürü) çok dikkatli bir şekilde belgeleyin, çünkü gelecekteki bakımcıların ebeveyn pom'un güncellenmiş bir sürümünü kullanmaları gerekiyorsa bunu yeniden yapması gerekir.
Thorbjørn Ravn Andersen

Elbette ebeveyn pomlarında bağımlılıkları kullanmamayı mı kastediyorsunuz? Ana pom, bağımlılık sürümlerini ve yaygın eklentileri yönetmek için hala çok kullanışlıdır. Sadece bağımlılığı enjekte etmek için kullanmak geri tepebilir - onu yalnızca sahip olunması gereken bağımlılıklar için kullanıyoruz (mikro hizmetler için bir ebeveyn için bir dizi temel ilkbahar önyükleme başlatıcısı gibi)
Amit Goldstein

Hayır, hafif bir ebeveyn pom kullan demiyorum. Ekibinizdeki diğerleri, ebeveyn pomunu kırpmanıza izin vermez çünkü diğer uygulamalar, ebeveyn pomundaki istemediğiniz önemsiz şeylere bağlıdır.
Sridhar Sarnobat

8

Bağımlılığı (çocuk pomda) scopesistem boş bir kavanozu işaret ederek yeniden tanımlayın:

<dependency>
    <groupId>dependency.coming</groupId>
    <artifactId>from.parent</artifactId>
    <version>0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/empty.jar</systemPath>
</dependency>

Kavanoz yalnızca tek bir boş dosya içerebilir:

touch empty.txt
jar cvf empty.txt

Windows'un 10 ı çalıştırmak zorunda Cevabınız için teşekkür ederiz notepad empty.classsonra jar cvf empty.jar empty.classboş bir kavanoz üretmek için.
Rov

1
Kötü bir uygulama gibi görünüyor
Piotr Żak

6

İstediğiniz mail.jar sürümünü açıkça beyan etmeyi denediniz mi? Maven'in bağımlılık çözümlemesi, diğer tüm sürümler üzerinde bağımlılık çözümlemesi için bunu kullanmalıdır.

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>test</groupId>
  <artifactId>jruby</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <parent>
        <artifactId>base</artifactId>
        <groupId>es.uniovi.innova</groupId>
        <version>1.0.0</version>
    </parent>
    <dependencies>          
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>VERSION-#</version>
            <scope>provided</scope>
        </dependency> 
        <dependency>
            <groupId>com.liferay.portal</groupId>
            <artifactId>ALL-DEPS</artifactId>
            <version>1.0</version>
            <scope>provided</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</project>

1
Yaklaşımınız, Pascal'ın 2 numaralı geçici çözümü de geçerlidir, aslında, posta bağımlılığının sağlandığı şekilde bildirilmesi gerektiğini de hesaba kattınız. Teşekkür ederim.
Miguel

Sağlanan kapsam benim için işe yaramadı. Kapsam testi kullandım, lütfen cevabımı kontrol edin. stackoverflow.com/a/55970293/4587961
Yan Khonski

3

En iyi bahis, her zaman devralmak istemediğiniz bağımlılıkları geçişsiz hale getirmektir.

Bunu, sağlanan kapsam ile ana pomda işaretleyerek yapabilirsiniz.

Yine de üst kuruluşun bu depoların sürümlerini yönetmesini istiyorsanız, <dependencyManagement>istediğiniz sürümleri açık bir şekilde devralmadan veya bu devralmayı alt öğelere geçirmeden kurmak için etiketini kullanabilirsiniz .


1

Bir paketi aradığınızda ancak bazı bağımlılıklarını istemediğinizde şöyle bir şey yapabilirsiniz (bu durumda eski log4j'nin eklenmesini istemedim çünkü yenisini kullanmam gerekiyordu):

<dependency>
  <groupId>package</groupId>
  <artifactId>package-pk</artifactId>
  <version>${package-pk.version}</version>

  <exclusions>
    <exclusion>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
    </exclusion>
  </exclusions>
</dependency>

<!-- LOG4J -->
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.5</version>
</dependency>
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-api</artifactId>
  <version>2.5</version>
</dependency>

Bu benim için çalışıyor ... ama java / maven konusunda oldukça yeniyim, bu yüzden belki de optimum değil.


Stack Overflow'a hoş geldiniz ve sürekli olarak sorularımı reddettiğim kaba insanların sizi gönderi yayınlamaktan caydırmasına izin vermeyin.
Sridhar Sarnobat

1

Bu kirli şeyi gerçekten yapmam gerekiyordu ... İşte nasıl

Bu bağımlılıkları kapsam ile yeniden tanımladım test. Kapsam providedbenim için işe yaramadı.

Yağ kavanozu oluşturmak için Spring Boot eklentisini kullanıyoruz. Biz modülü var Common'ı örneği Springfox havalı-2 için, ortak kütüphaneleri tanımlar. Benim süper hizmet ebeveyn olması gerekir Common'ı (bunu yapmak istemiyor, ancak şirket kuvvet kuralları!)

Yani benim ebeveynimde ya da müşterimde pom var

<dependencyManagement>

    <!- I do not need Springfox in one child but in others ->

    <dependencies>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${swagger.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>com.google.guava</groupId>
                    <artifactId>guava</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${swagger.version}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-bean-validators</artifactId>
            <version>${swagger.version}</version>
        </dependency>

       <!- All services need them ->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${apache.poi.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

Ve süper hizmet pomum.

<name>super-service</name>
<parent>
    <groupId>com.company</groupId>
    <artifactId>common</artifactId>
    <version>1</version>
</parent>

<dependencies>

    <!- I don't need them ->

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-bean-validators</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-core</artifactId>
        <version>2.8.0</version>
        <scope>test</scope>
    </dependency>

    <!- Required dependencies ->

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
     <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
    </dependency>
</dependencies>

Bu, son şişman eserin boyutu

82.3 MB (86,351,753 bytes) - redefined dependency with scope test
86.1 MB (90,335,466 bytes) - redefined dependency with scope provided
86.1 MB (90,335,489 bytes) - without exclusion

Ayrıca bu cevaptan bahsetmeye değer - bunu yapmak istedim ama tembelim ... https://stackoverflow.com/a/48103554/4587961


0

Ana pomu pom tipi ile bağımlılık olarak ekleyebilir ve bunun üzerine dışlama yapabiliriz. Çünkü her nasılsa ebeveyn pom indirilir. Bu benim için çalıştı

<dependency>
  <groupId>com.abc.boot</groupId>
  <artifactId>abc-boot-starter-parent</artifactId>
  <version>2.1.5.RELEASE</version>
  <type>pom</type>
  <exclusions>
    <exclusion>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
    </exclusion>
  </exclusions>   
</dependency>
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.