Maven-3 zaman damgalı anlık görüntülerle verimli bir şekilde nasıl başa çıkarsınız?


87

Şimdi maven-3 yaptığını damla desteği <uniqueVersion> false için </ uniqueVersion> anlık eserler için gerçekten timestamped anlık görüntülerini kullanmak gerekir gibi görünüyor. Özellikle maven 3'ü dahili olarak kullanan m2eclipse bundan etkilenmiş gibi görünüyor, SNAPSHOTS benzersiz olmadığında güncelleme-anlık görüntüleri çalışmıyor.

Tüm anlık görüntüleri uniqueVersion = false olarak ayarlamak daha önce en iyi uygulama gibi görünüyordu

Şimdi, zaman damgalı sürüme geçmek büyük bir sorun gibi görünmüyor, sonuçta bunlar, eski anlık görüntüleri düzenli aralıklarla silebilen merkezi bir bağlantı noktası deposu tarafından yönetiliyor.

Sorun yerel geliştirici iş istasyonlarında. Yerel depoları , benzersiz anlık görüntülerle hızla çok büyüyor .

Bu problemle nasıl başa çıkılır?

Şu anda aşağıdaki olası çözümleri görüyorum:

  • Geliştiricilerden depoyu düzenli aralıklarla temizlemelerini isteyin (bu, silinmesi uzun ve gerekli olan her şeyi indirmek daha da uzun sürdüğü için çok fazla sıkıntıya yol açar)
  • Yerel depodaki tüm SNAPSHOT dizinlerini silen ve geliştiricilerden bu komut dosyasını zaman zaman çalıştırmalarını isteyen bir komut dosyası oluşturun (ilkinden daha iyidir, ancak mevcut anlık görüntüleri çalıştırmak ve indirmek hala biraz zaman alır)
  • bağımlılığı kullanın: purge-local-repository plugin (Eclipse'den çalıştırıldığında, açık dosyalar nedeniyle sorun yaşıyor, her projeden çalıştırılması gerekiyor)
  • Her iş istasyonunda bağlantı noktası kurun ve eski anlık görüntüleri temizlemek için bir iş ayarlayın (en iyi sonuç, ancak 50'den fazla bağlantı noktası sunucusunu korumak istemiyorum, ayrıca geliştirici iş istasyonlarında bellek her zaman kısıtlıdır)
  • SNAPSHOTS kullanmayı tamamen bırak

Yerel deponuzun sabit disk alanınızı doldurmasını önlemenin en iyi yolu nedir?

Güncelleme:

Davranışı doğrulamak ve daha fazla bilgi vermek için küçük bir bağlantı noktası sunucusu kuruyorum, iki proje (a ve b) oluşturup şunu deneyin:

a:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>de.glauche</groupId>
  <artifactId>a</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <distributionManagement>
    <snapshotRepository>
        <id>nexus</id>
        <name>nexus</name>
        <url>http://server:8081/nexus/content/repositories/snapshots</url>
    </snapshotRepository>
  </distributionManagement>

</project>

b:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>de.glauche</groupId>
  <artifactId>b</artifactId>
  <version>0.0.1-SNAPSHOT</version>
    <distributionManagement>
    <snapshotRepository>
        <id>nexus</id>
        <name>nexus</name>
        <url>http://server:8081/nexus/content/repositories/snapshots/</url>
    </snapshotRepository>
  </distributionManagement>
 <repositories>
    <repository>
        <id>nexus</id>
        <name>nexus</name>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <url>http://server:8081/nexus/content/repositories/snapshots/</url>
    </repository>
 </repositories>
  <dependencies>
    <dependency>
        <groupId>de.glauche</groupId>
        <artifactId>a</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
  </dependencies>
</project>

Şimdi, maven'i kullandığımda ve "a" üzerinde "konuşlandır" ı çalıştırdığımda,

a-0.0.1-SNAPSHOT.jar
a-0.0.1-20101204.150527-6.jar
a-0.0.1-SNAPSHOT.pom
a-0.0.1-20101204.150527-6.pom

yerel depoda. Dağıtım hedefini her çalıştırdığımda yeni bir zaman damgası sürümü ile. Aynı durum, Anlık Görüntüleri nexus sunucusundan güncellemeye çalıştığımda da oluyor ("a" Projesini kapatın, yerel depodan silin, "b" oluşturun)

Çok sayıda anlık görüntünün oluşturulduğu bir ortamda (hudson sunucusunu düşünün ...), yerel depo eski sürümlerle hızla dolar

Güncelleme 2:

Bunun nasıl ve neden başarısız olduğunu test etmek için birkaç test daha yaptım. Her test temiz her şeye karşı çalıştırılır (de / glauche hem makinelerden hem de bağlantı noktasından silinir)

  • mvn 2.2.1 ile mvn dağıtımı:

A makinesindeki yerel depo, snapshot.jar + snapshot-timestamp.jar içeriyor

AMA: bağlantı noktasında yalnızca bir zaman damgalı jar, meta veriler şunları okur:

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <groupId>de.glauche</groupId>
  <artifactId>a</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <versioning>
    <snapshot>
      <timestamp>20101206.200039</timestamp>

      <buildNumber>1</buildNumber>
    </snapshot>
    <lastUpdated>20101206200039</lastUpdated>
  </versioning>
</metadata>
  • m2eclipse'de güncelleme bağımlılıklarını (makine B'de) çalıştır (katıştırılmış m3 final) -> yerel depoda snapshot.jar + snapshot-timestamp.jar :(
  • harici maven 2.2.1 ile paket hedefini çalıştırın -> yerel depoda snapshot.jar + snapshot-timestamp.jar :(

Tamam, sonra maven 3.0.1 ile deneyin (a projesinin tüm izlerini kaldırdıktan sonra)

  • A makinesindeki yerel depo daha iyi görünüyor, yalnızca bir zaman damgalı olmayan jar

  • bağlantı noktasında yalnızca bir zaman damgalı jar, meta veriler şunları okur:

    de.glauche a 0.0.1-SNAPSHOT

    <snapshot>
      <timestamp>20101206.201808</timestamp>
      <buildNumber>3</buildNumber>
    </snapshot>
    <lastUpdated>20101206201808</lastUpdated>
    <snapshotVersions>
      <snapshotVersion>
        <extension>jar</extension>
        <value>0.0.1-20101206.201808-3</value>
        <updated>20101206201808</updated>
      </snapshotVersion>
      <snapshotVersion>
        <extension>pom</extension>
        <value>0.0.1-20101206.201808-3</value>
        <updated>20101206201808</updated>
      </snapshotVersion>
    </snapshotVersions>
    

  • m2eclipse'de güncelleme bağımlılıklarını (makine B'de) çalıştır (katıştırılmış m3 final) -> yerel depoda snapshot.jar + snapshot-timestamp.jar :(

  • harici maven 2.2.1 ile paket hedefini çalıştırın -> yerel depoda snapshot.jar + snapshot-timestamp.jar :(

Özetlemek gerekirse: maven3'teki "konuşlandırma" hedefi 2.2.1'den daha iyi çalışıyor, oluşturma makinesindeki yerel depo iyi görünüyor. Ancak, alıcı her zaman birçok zaman damgalı sürümle sonuçlanır ...

Neyi yanlış yapıyorum ?

Güncelleme 3

Ayrıca çeşitli diğer konfigürasyonları da test ettim, önce nexus'u yapay -> aynı davranışla değiştirdim. Ardından anlık görüntüleri havuz yöneticisinden indirmek için linux maven 3 istemcilerini kullanın -> yerel depoda hala zaman damgalı anlık görüntüler var :(


Yalnızca yerel .m2 \ depo kısmı hakkında, bir (Jenkins) derleme sunucusundaki yerel depoya odaklanan ilgili soru: stackoverflow.com/q/9729076/223837 .
MarnixKlooster ReinstateMonica

İşte Apcahe Maven Comptability Notes - cwiki.apache.org/confluence/display/MAVEN/…
aka_sh

Yanıtlar:


36

<uniqueVersion>Yapılandırma noktası olarak Maven deposu gibi üzere (mvn dağıtmak ile) dağıtılan eserler uygulanır.

Bunları Nexus'tan kaldırmak için, SNAPSHOT havuzunu her gün temizlemek için kolayca otomatik bir iş oluşturabilirsiniz. Belirli sayıda şekil görüntüsünü tutacak veya belirli bir süre saklayacak şekilde yapılandırılabilir. Çok kolay ve harika çalışıyor.

Bir geliştirici makinesindeki yerel depodaki yapılar, oraya "yükleme" hedefinden ulaşır ve bu zaman damgalarını kullanmayın ... siz aynı zamanda revizyon numarasını da (örn. 1.0.0- SNAPSHOT'dan 1.0.1-SNAPSHOT'a).


1
Sorun şu ki, "kurulum" hedefi birçok geliştiricinin bulunduğu dağıtılmış bir ortamda çok fazla kullanılmıyor. Ayrıca, her gün oldukça sık gerçekleşen her cv işleminde yeni anlık görüntüler oluşturan (ve dağıtan) bir hudson sunucusu kullanıyoruz. Nexus snapshot delete mechainsm'i biliyordum, olası geçici çözümlerin listesine bakın.
mglauche

Her geliştirme makinesinin altında "yerel" bir havuz bulunmalı ~/.m2/repositoryve her birinin pom.xmlLAN'ınızdaki Nexus'un tek bir örneğini gösteren bir depo tanımı olmalıdır. (tıpkı gösterdiğiniz gibi). Her Subversion taahhüdüne dayanan Hudson ile birlikte bu kurulumumuz var ve harika çalışıyor. SNAPSHOT yapıları, Nexus'a "dağıtılır" ve burada toplanır ve haftalık olarak temizlenir. Geliştirici makineleri en son SNAPSHOT'u Nexus'tan otomatik olarak indirir ~/.m2/repositoryve daha önce indirilenin yerini alır. Geliştiriciler hiçbir zaman kendi Nexus örneğine sahip olmamalıdır.
HDave

2
Güncellemenizi okudum ve ekleyeceğim bir şey daha var: Zaman damgalı yapılar asla yerel (~ / .m2 / depo) deponuzda görülmemelidir. Eğer öyleyse, bir sorun var. Yalnızca Nexus'un içinde görülmeleri gerekir. Nexus'un içinde, evet, çabucak toplanıyorlar. Potansiyel olarak günde yüzlerce MB. Bir bağlantı noktası işi, miktarı küçük tutmak için bunları günlük olarak daha kolay temizleyebilir.
HDave

6
Onlar kesinlikle yerel depo (~ / .m2 / depo bir), onlar orada "dağıtma" hedefini çalıştırdıktan sonra sona sona yapmak ve mvn -U üzerinde (yani B projesi) bağlı proje üzerinde yükleyin. Hatta maven 2.2.1 ve maven 3 ile test ettim, ikisi de aynı davranışa sahip.
mglauche

2
Sanırım şimdi anlıyorum ... geliştirme bir "dağıtma" yaptığında orada görünmüyorlar, bunun yerine geliştirici bağımlı bir proje oluşturduğunda. O zaman, yukarı akış projesinin en son SNAPSHOT'u Nexus'tan ~ / .m2 / havuzuna indirilir ve zaman damgası dosya adının bir parçası olarak bozulmadan bırakılır. Bu doğru mu?
HDave

14

Bu eklenti, projenin yapıtlarını yerel depodan kaldırır. Büyük yerel anlık görüntünün yalnızca bir kopyasını saklamak için kullanışlıdır.

<plugin>         
    <groupId>org.codehaus.mojo</groupId>         
    <artifactId>build-helper-maven-plugin</artifactId>         
    <version>1.7</version>         
    <executions>           
        <execution>             
            <id>remove-old-artifacts</id>             
            <phase>package</phase>             
            <goals>               
                <goal>remove-project-artifact</goal>             
            </goals>            
            <configuration>  
                <removeAll>true</removeAll><!-- When true, remove all built artifacts including all versions. When false, remove all built artifacts of this project version -->             
            </configuration>          
        </execution>         
    </executions>       
</plugin>

7

Önerilen çözümlerin hiçbirini beğenmedim. Maven önbelleğini silmek genellikle ağ trafiğini önemli ölçüde artırır ve oluşturma sürecini yavaşlatır. build-helper-maven-plugin yalnızca tek bir artefakt ile yardımcı oluyor, basit bir komutla tüm güncel olmayan zaman damgalı anlık görüntü yapılarını yerel önbellekten temizleyebilecek bir çözüm istedim. Birkaç gün aradıktan sonra pes ettim ve küçük bir program yazmaya karar verdim. Son program çevremizde oldukça iyi çalışıyor gibi görünüyor. Bu yüzden, bu tür bir araca ihtiyaç duyabilecek diğerleriyle paylaşmaya karar verdim. Kaynaklar github'dan alınabilir: https://github.com/nadestin/tools/tree/master/MavenCacheCleanup


@HDave Burada pom parçasını doğru şekilde biçimlendirmeyi başaramadım, https://github.com/nadestin/tools/wiki/m2cachecleanup-maven-plugin adresinden kontrol edin . Jenkins slave'lerimizde bu yardımcı program günlük ~ 200Mb disk alanını geri kazanır.
yurinadestin

2

Bunun uzak depo parçasıyla ilgili olarak, SNAPSHOT'ların düzenli aralıklarla temizlenmesini tartışan önceki yanıtların işe yarayacağını düşünüyorum. Ancak, sorunuzun yerel geliştirici iş istasyonu senkronizasyonu kısmına kimse değinmedi.

Henüz Maven3'ü kullanmaya başlamadık, bu yüzden SNAPSHOT'ların yerel makinelerde kurulmaya başladığını henüz görmedik.

Ancak m2eclipse ile ilgili farklı sorunlarımız oldu. "Çalışma Alanı Çözünürlüğü" nü etkinleştirdiğimizde ve proje çalışma alanımızda mevcut olduğunda, kaynak güncellemeleri genellikle bizi en uç noktada tutar. Ancak m2eclipse'in Nexus'ta yakın zamanda yayınlanan eserlerle kendisini güncellemesini sağlamanın çok zor olduğunu gördük. Ekibimizde benzer sorunlar yaşıyoruz ve bu özellikle sorunlu çünkü çok büyük bir proje grafiğimiz var ... çalışma alanınızda olmayacak ancak SNAPSHOT'lar sık ​​sık yayınlanacak olan birçok bağımlılık var.

Bunun, SNAPSHOT'ları olması gerektiği gibi işlemediği m2eclipse'deki bir soruna geri döndüğünden oldukça eminim. Tutulma içindeki Maven konsolunda m2eclipse'in önbelleğe alınmış bir sürümü olduğu için yakın zamanda yayınlanan bir SNAPSHOT güncellemesini atladığını söylediğini görebilirsiniz. Bir çalıştırma yapılandırmasından veya komut satırından -U yaparsanız, Maven meta veri değişikliğini alır. Ancak "Anlık Görüntülerini Güncelle ..." seçimi m2eclipse'e Maven'in bu önbelleği sonlandırmasını söylemelidir. Geçecek gibi görünmüyor. Oy vermekle ilgileniyorsanız, bunun için dosyalanmış bir hata var gibi görünüyor: https://issues.sonatype.org/browse/MNGECLIPSE-2608

Bundan bir yerde bir yorumda bahsetmiştin.

Bu sorun için en iyi çözüm, geliştiricilerin, işler m2eclipse içinden bozulmaya başladığında yerel iş istasyonlarını temizlemelerini sağlamak gibi görünüyor. Farklı bir soruna benzer bir çözüm ... Diğerleri Maven 2.2.1 ve 3 destek m2eclipse ile ilgili sorunlar bildirdi ve ben de aynısını gördüm.

Umarım Maven3 kullanıyorsanız, onu yalnızca en son SNAPSHOT'u çekecek şekilde yapılandırabilir ve deponun söylediği süre boyunca (veya elinizle sonlandırana kadar) önbelleğe alabilirsiniz. Umarım yerel deponuzda bir grup SNAPSHOT'a ihtiyacınız olmayacaktır.

Bu, manuel olarak bir mvn installonlar üzerinde. SNAPSHOT'ların bir yapı sunucusu gibi bir ortamda oluşmasını nasıl engelleyeceğimize gelince, her derlemenin kendi çalışma alanını ve yerel deposunu kullanmasını sağlayarak bu mermiden kaçtık (yine de Maven 2.2.1'de, POM'lar her zaman ~ / .m2 / depodan çıkıyor gibi görünüyor) Ekstra SNAPSHOT'lar gerçekten sadece tek bir yapı için takılıyorlar ve sonra bırakılıyorlar (ve sıfırdan tekrar indiriliyorlar). Dolayısıyla, bu yaklaşımın başlangıçta daha fazla yer kapladığını gördük, ancak her şeyin tek bir depodan çözülmesinden daha kararlı kalma eğilimindedir. Bu seçenek (Hudson'da) "Özel Maven deposunu kullan" olarak adlandırılır ve Maven ile oluşturmayı seçtiğinizde proje yapılandırmalarındaki Oluştur bölümünün Gelişmiş düğmesinin altındadır. İşte bu seçenek için yardım açıklaması:

Normalde Hudson, Maven tarafından belirlenen yerel Maven deposunu kullanır - tam süreç belgelenmemiş gibi görünür, ancak ~ / .m2 / repository'dir ve ~ / .m2 / settings.xml dosyasında geçersiz kılınabilir (daha fazla ayrıntı için referansa bakın) .) Bu, normalde aynı düğümde yürütülen tüm işlerin tek bir Maven deposunu paylaştığı anlamına gelir. Bunun iyi yanı, disk alanından tasarruf edebilmenizdir, ancak bunun dezavantajı, bazen bu yapıların birbirini engelleyebilmesidir. Örneğin, sadece yerel deponuzda tüm bağımlılıklara sahip olduğunuz için, POM'daki depoların hiçbirinde bunlara sahip olmamasına rağmen, yapıların yanlış bir şekilde başarılı olmasıyla sonuçlanabilirsiniz.

Aynı yerel depoyu kullanmaya çalışan eşzamanlı Maven işlemleriyle ilgili bildirilen bazı sorunlar da vardır.

Bu seçenek işaretlendiğinde, Hudson Maven'e yerel Maven deposu olarak $ WORKSPACE / .repository'yi kullanmasını söyleyecektir. Bu, her işin yalnızca kendisi için kendi izole Maven deposuna sahip olacağı anlamına gelir. Ek disk alanı tüketimi pahasına yukarıdaki sorunları düzeltir.

Bu seçeneği kullanırken, uzaktaki Maven depolarına çok sık vurmak zorunda kalmamak için bir Maven yapı yöneticisi kurmayı düşünün.

Hudson'da yürütülen tüm Maven işlerinde bu modu etkinleştirmeyi tercih ediyorsanız, burada açıklanan tekniğe başvurun.

Bunun yardımcı olacağını umuyoruz - sorununuzu çözmüyorsa lütfen nereleri kaçırdığımı bildirin.


Yukarıda bahsedilen hata düzeltildi: bugs.eclipse.org/bugs/show_bug.cgi?id=339527
HDave

1

Harika bir şekilde , zaman damgalı dosyaları silmek artifact-0.0.1-20101204.150527-6.jarçok basit olabilir:

root = 'path to your repository'

new File(root).eachFileRecurse {
  if (it.name.matches(/.*\-\d{8}\.\d{6}\-\d+\.[\w\.]+$/)) {
    println 'Deleting ' + it.name
    it.delete()
  }
}

Groovy'yi kurun , komut dosyasını bir dosyaya kaydedin ve yürütmeyi her hafta, başlangıçta, oturum açmada ve size uygun olan her durumda programlayın.

Veya yürütmeyi gmavenplus-eklentisini kullanarak maven yapısına bile bağlayabilirsiniz . Dikkat edin, depo konumu maven tarafından mülke nasıl ayarlanır settings.localRepositoryve ardından yapılandırma aracılığıyla değişkene bağlanır repository:

  <plugin>
    <groupId>org.codehaus.gmavenplus</groupId>
    <artifactId>gmavenplus-plugin</artifactId>
    <version>1.3</version>
    <executions>
      <execution>
        <phase>install</phase>
        <goals>
          <goal>execute</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <properties>
        <property>
          <name>repository</name>
          <value>${settings.localRepository}</value>
        </property>
      </properties>
      <scripts>
        <script><![CDATA[
          new File(repository).eachFileRecurse {
            if (it.name.matches(/.*\-\d{8}\.\d{6}\-\d+\.[\w\.]+$/)) {
              println 'Deleting snapshot ' + it.getAbsolutePath()
              it.delete()
            }
          }
        ]]></script>
      </scripts>
    </configuration>
    <dependencies>
      <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>2.3.7</version>
        <scope>runtime</scope>
      </dependency>
    </dependencies>
  </plugin>  

0

POM dosyanıza aşağıdaki parametreyi ekleyin

POM

<configuration>
<outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename>
</configuration>

https://maven.apache.org/plugins/maven-dependency-plugin/copy-mojo.html

POM örneği

<plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.10</version>
        <executions>
          <execution>
            <id>copy</id>
            <phase>package</phase>
            <goals>
              <goal>copy</goal>
            </goals>
            <configuration>
              <artifactItems>
                <artifactItem>
                  <groupId>junit</groupId>
                  <artifactId>junit</artifactId>
                  <version>3.8.1</version>
                  <type>jar</type>
                  <overWrite>false</overWrite>
                  <outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
                  <destFileName>optional-new-name.jar</destFileName>
                </artifactItem>
              </artifactItems>
              **<outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename>**
              <outputDirectory>${project.build.directory}/wars</outputDirectory>
              <overWriteReleases>false</overWriteReleases>
              <overWriteSnapshots>true</overWriteSnapshots>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

Jenkins'te yapılandırın:

// copy artifact 
copyMavenArtifact(artifact: "commons-collections:commons-collections:3.2.2:jar", outputAbsoluteArtifactFilename: "${pwd()}/target/my-folder/commons-collections.jar")
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.