Sekarang setelah maven-3 memberikan dukungan untuk <uniqueVersion> false </uniqueVersion> untuk artefak snapshot, tampaknya Anda benar-benar perlu menggunakan SNAPSHOTS yang diberi stempel waktu. Terutama m2eclipse, yang menggunakan maven 3 secara internal tampaknya terpengaruh dengannya, update-snapshot tidak berfungsi jika SNAPSHOTS tidak unik.
Tampaknya praktik terbaik sebelum menyetel semua snapshot ke uniqueVersion = false
Sekarang, tampaknya tidak ada masalah besar untuk beralih ke versi timestamped, bagaimanapun juga mereka dikelola oleh repositori nexus pusat, yang mampu menghapus snapshot lama di intervalls biasa.
Masalahnya adalah workstation pengembang lokal. Repositori lokal mereka dengan cepat tumbuh sangat besar dengan snapshot unik.
Bagaimana cara mengatasi masalah ini?
Sekarang saya melihat kemungkinan solusi berikut:
- Minta pengembang untuk membersihkan repositori secara berkala (yang menyebabkan banyak fustration, karena butuh waktu lama untuk menghapus dan bahkan lebih lama untuk mengunduh semua yang diperlukan)
- Siapkan beberapa skrip yang menghapus semua direktori SNAPSHOT dari repositori lokal dan minta pengembang untuk menjalankan skrip itu dari waktu ke waktu (lebih baik dari yang pertama, tetapi masih membutuhkan waktu untuk menjalankan dan mengunduh snapshot saat ini)
- gunakan dependensi: plugin purge-local-repository (Apakah mengalami masalah saat dijalankan dari eclipse, karena file yang terbuka, perlu dijalankan dari setiap proyek)
- mengatur nexus di setiap workstation dan mengatur pekerjaan untuk membersihkan snapshot lama (hasil terbaik, tetapi saya tidak ingin mempertahankan 50+ server nexus, ditambah memori selalu ketat pada workstation pengembang)
- berhenti menggunakan SNAPSHOTS sama sekali
Apa cara terbaik untuk mencegah repositori lokal Anda mengisi ruang hard drive Anda?
Memperbarui:
Untuk memverifikasi perilaku dan untuk memberikan info lebih lanjut, saya menyiapkan server nexus kecil, membangun dua proyek (a dan b) dan mencoba:
Sebuah:
<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>
Sekarang, ketika saya menggunakan maven dan menjalankan "deploy" pada "a", saya akan melakukannya
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
di repositori lokal. Dengan versi stempel waktu baru setiap kali saya menjalankan target penerapan. Hal yang sama terjadi ketika saya mencoba memperbarui Snapshot dari server nexus (tutup Project "a", hapus dari repositori lokal, build "b")
Dalam lingkungan di mana banyak snapshot dibangun (pikirkan server hudson ...), reposioty lokal terisi dengan versi lama dengan cepat
Perbarui 2:
Untuk menguji bagaimana dan mengapa ini gagal, saya melakukan beberapa tes lagi. Setiap pengujian dijalankan terhadap semua yang bersih (de / glauche dihapus dari mesin dan nexus)
- mvn menyebarkan dengan maven 2.2.1:
repositori lokal pada mesin A memang berisi snapshot.jar + snapshot-timestamp.jar
TAPI: hanya satu botol dengan stempel waktu di nexus, metadata terbaca:
<?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>
- jalankan dependensi pembaruan (pada mesin B) di m2eclipse (m3 final tertanam) -> repositori lokal memiliki snapshot.jar + snapshot-timestamp.jar :(
- menjalankan tujuan paket dengan maven 2.2.1 eksternal -> repositori lokal memiliki snapshot.jar + snapshot-timestamp.jar :(
Ok, selanjutnya coba dengan maven 3.0.1 (setelah menghapus semua jejak proyek a)
repositori lokal pada mesin A terlihat lebih baik, hanya satu botol non-timestamped
hanya satu botol dengan stempel waktu di nexus, metadata berbunyi:
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>
jalankan dependensi pembaruan (pada mesin B) di m2eclipse (m3 final tertanam) -> repositori lokal memiliki snapshot.jar + snapshot-timestamp.jar :(
menjalankan tujuan paket dengan maven 2.2.1 eksternal -> repositori lokal memiliki snapshot.jar + snapshot-timestamp.jar :(
Jadi, untuk rekap: Tujuan "menyebarkan" di maven3 bekerja lebih baik daripada di 2.2.1, repositori lokal pada mesin pembuat terlihat baik-baik saja. Namun, receiver selalu mendapatkan banyak versi dengan waktu ...
Apa yang saya lakukan salah?
Perbarui 3
Saya juga menguji berbagai konfigurasi lain, pertama-tama ganti nexus dengan artifactory -> perilaku yang sama. Kemudian gunakan klien linux maven 3 untuk mengunduh snapshot dari manajer repositori -> repositori lokal masih memiliki snapshot yang diberi stempel waktu :(
Jawaban:
The
<uniqueVersion>
konfigurasi diterapkan pada artefak yang dikerahkan (via menyebarkan mvn) ke Maven repositori seperti Nexus.Untuk menghapus ini dari Nexus, Anda dapat dengan mudah membuat pekerjaan otomatis untuk membersihkan repositori SNAPSHOT setiap hari. Ini dapat dikonfigurasi untuk mempertahankan sejumlah shapshots atau menyimpannya untuk jangka waktu tertentu. Ini sangat mudah dan berfungsi dengan baik.
Artefak di repositori lokal pada mesin pengembang sampai ke sana dari tujuan "instal" dan tidak menggunakan cap waktu ini ... mereka hanya terus mengganti satu-satunya versi SNAPSHOT kecuali Anda juga menambah nomor revisi (misalnya 1.0.0- SNAPSHOT hingga 1.0.1-SNAPSHOT).
sumber
~/.m2/repository
dan masingpom.xml
- masing harus memiliki definisi repositori yang menunjuk ke satu instance Nexus di LAN Anda. (seperti yang Anda tunjukkan). Kami memiliki pengaturan ini, bersama dengan Hudson yang membangun setiap komitmen Subversion dan bekerja dengan baik. Versi SNAPSHOT "diterapkan" ke Nexus tempat mereka mengumpulkan dan dibersihkan setiap minggu. Mesin pengembang secara otomatis mengunduh SNAPSHOT terbaru dari Nexus ke~/.m2/repository
dan menggantikan yang diunduh sebelumnya. Pengembang tidak boleh memiliki instance Nexus sendiri.Plugin ini menghapus artefak proyek dari repositori lokal. Berguna untuk menyimpan hanya satu salinan snapshot lokal yang besar.
<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>
sumber
Yah, saya tidak suka solusi yang diusulkan. Menghapus cache maven sering kali secara signifikan meningkatkan lalu lintas jaringan dan memperlambat proses build. build-helper-maven-plugin hanya membantu dengan satu artefak, saya menginginkan solusi yang dapat membersihkan semua artefak snapshot cap waktu yang sudah usang dari cache lokal dalam satu perintah sederhana. Setelah beberapa hari mencari, saya menyerah dan memutuskan untuk menulis program kecil. Program terakhir tampaknya berjalan cukup baik di lingkungan kita. Jadi saya memutuskan untuk membagikannya dengan orang lain yang mungkin membutuhkan alat tersebut. Sumber dapat ditarik dari github: https://github.com/nadestin/tools/tree/master/MavenCacheCleanup
sumber
Sejauh bagian repositori jarak jauh ini, saya pikir jawaban sebelumnya yang membahas pembersihan SNAPSHOT pada interval reguler akan berfungsi. Tetapi tidak ada yang membahas bagian sinkronisasi stasiun kerja pengembang lokal dari pertanyaan Anda.
Kami belum mulai menggunakan Maven3, jadi kami belum melihat SNAPSHOT mulai dibangun di komputer lokal.
Tapi kami punya masalah berbeda dengan m2eclipse. Saat kami mengaktifkan "Resolusi Ruang Kerja" dan proyek ada di dalam ruang kerja kami, pembaruan sumber biasanya membuat kami tetap update. Tapi kami merasa sangat sulit mendapatkan m2eclipse untuk memperbarui dirinya sendiri dengan artefak yang baru-baru ini diterbitkan di Nexus. Kami mengalami masalah serupa dalam tim kami dan ini sangat bermasalah karena kami memiliki grafik proyek yang sangat besar ... ada banyak dependensi yang tidak akan ada di ruang kerja Anda tetapi SNAPSHOT akan sering dipublikasikan.
Saya cukup yakin ini kembali ke masalah di m2eclipse di mana ia tidak menangani SNAPSHOT persis seperti yang seharusnya. Anda dapat melihat di konsol Maven di dalam gerhana di mana m2eclipse memberi tahu Anda bahwa ia melewatkan pembaruan SNAPSHOT yang baru-baru ini diterbitkan karena versi cache-nya. Jika Anda melakukan -U dari konfigurasi proses atau dari baris perintah, Maven akan mengambil perubahan metadata. Tapi pilihan "Perbarui Snapshots ..." seharusnya memberitahu m2eclipse agar Maven mengakhiri cache ini. Tampaknya tidak diteruskan. Tampaknya ada bug di luar sana yang diajukan untuk ini jika Anda tertarik untuk memilihnya: https://issues.sonatype.org/browse/MNGECLIPSE-2608
Anda menyebutkan ini dalam komentar di suatu tempat.
Solusi terbaik untuk masalah ini tampaknya meminta pengembang membersihkan workstation lokal mereka ketika hal-hal mulai rusak dari dalam m2eclipse. Solusi serupa untuk masalah yang berbeda ... Orang lain telah melaporkan masalah dengan Maven 2.2.1 dan 3 m2eclipse dukungan, dan saya telah melihat hal yang sama.
Saya berharap jika Anda menggunakan Maven3, Anda dapat mengkonfigurasinya untuk hanya menarik SNAPSHOT terbaru, dan menyimpannya selama waktu yang dikatakan repositori (atau sampai Anda kedaluwarsa dengan tangan). Mudah-mudahan Anda tidak perlu memiliki banyak SNAPSHOT yang ada di repositori lokal Anda.
Itu kecuali jika Anda berbicara tentang server build yang secara manual melakukan file
mvn install
pada mereka. Sejauh bagaimana mencegah SNAPSHOT membangun di lingkungan seperti server build, kami telah menghindari peluru itu dengan meminta setiap build menggunakan ruang kerja dan repositori lokalnya sendiri (meskipun, di Maven 2.2.1, hal-hal tertentu seperti POM tampaknya selalu keluar dari ~ / .m2 / repositori) SNAPSHOT ekstra benar-benar hanya bertahan untuk satu build dan kemudian dibuang (dan diunduh lagi dari awal). Jadi kita telah melihat pendekatan ini akhirnya memakan lebih banyak ruang untuk memulai, tetapi cenderung tetap lebih stabil daripada menyelesaikan semuanya dari satu repositori. Opsi ini (di Hudson) disebut "Gunakan repositori Maven pribadi" dan berada di bawah tombol Lanjutan dari bagian Bangun pada konfigurasi proyek ketika Anda memilih untuk membangun dengan Maven. Berikut adalah deskripsi bantuan untuk opsi itu:Semoga ini bisa membantu - jika tidak mengatasi masalah Anda, beri tahu saya di mana saya ketinggalan.
sumber
Secara groovy , menghapus file yang
artifact-0.0.1-20101204.150527-6.jar
diberi stempel waktu bisa sangat sederhana: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() } }
Instal Groovy , simpan skrip ke dalam file dan jadwalkan eksekusi setiap minggu, mulai, masuk, apa pun yang cocok untuk Anda.
Atau, Anda bahkan dapat mentransfer eksekusi ke maven build, menggunakan gmavenplus-plugin . Perhatikan, bagaimana lokasi repositori diatur oleh maven ke dalam properti
settings.localRepository
dan kemudian diikat melalui konfigurasi ke dalam variabelrepository
:<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>
sumber
Tambahkan parameter berikut ke dalam file POM Anda
POM
<configuration> <outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename> </configuration>
https://maven.apache.org/plugins/maven-dependency-plugin/copy-mojo.html
Contoh POM
<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>
Konfigurasikan di Jenkins:
// copy artifact copyMavenArtifact(artifact: "commons-collections:commons-collections:3.2.2:jar", outputAbsoluteArtifactFilename: "${pwd()}/target/my-folder/commons-collections.jar")
sumber