Maven-3タイムスタンプのスナップショットを効率的にどのように扱っていますか?
質問
今、Maven-3がやった ドロップサポート のためにu003CuniqueVersion>偽u003C/uniqueVersion>スナップショットアーティファクトの場合、タイムスタンプのスナップショットを本当に使用する必要があるようです。特にM2Eclipseは、Maven 3を内部的に使用するように思われますが、スナップショットが一意でない場合、更新スナップショットは機能しません。
それは最高のようでした 前に練習します すべてのスナップショットをsinqueversion = falseに設定するには
今では、タイムスタンプ付きバージョンに切り替えることは大きな問題ではないようです。
問題は、地元の開発者ワークステーションです。彼らのローカルリポジトリはすぐに成長します 非常に ユニークなスナップショットを備えた大きい。
この問題に対処する方法は?
今、私は、可能な解決策を見ています:
- 開発者に通常の間隔でリポジトリをパージするように依頼します(これは多くのフラストレーションにつながります。削除するのに長い時間がかかり、必要なものをすべてダウンロードするのにさらに時間がかかるため)
- すべてを削除するスクリプトを設定します スナップショット ローカルリポジトリのディレクトリと開発者に、そのスクリプトを時々実行するように依頼します(最初のスクリプトよりも優れていますが、現在のスナップショットを実行してダウンロードするのにかなりの時間がかかります)
- 依存関係の使用:Purge-Local-Repositoryプラグイン(Eclipseから実行すると、開いたファイルのために実行され、各プロジェクトから実行する必要があります)
- すべてのワークステーションにネクサスをセットアップし、古いスナップショットをクリーニングするためのジョブを設定します(最良の結果ですが、50以上のNexusサーバーを維持したくありません。
- スナップショットの使用をやめてください
地元のリポジトリがハードドライブスペースを埋めないようにするための最良の方法は何ですか?
アップデート:
Beaviourを確認し、詳細情報を提供するために、小さなNexusサーバーをセットアップし、2つのプロジェクト(AとB)を作成して試してみてください。
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>
さて、私がMavenを使用して「A」で「展開」を実行するとき、私は持っています
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
ローカルリポジトリで。展開ターゲットを実行するたびに新しいタイムスタンプバージョンを使用します。 Nexusサーバーからスナップショットを更新しようとすると同じことが起こります(「A」プロジェクトを閉じ、ローカルリポジトリから削除し、「B」をビルドします)
多くのスナップショットが構築される環境で(ハドソンサーバーを考えてください...)、ローカルレポジオティは古いバージョンでいっぱいになります 速い
更新2:
これがどのように、そしてなぜ失敗しているのかをテストするために、私はさらにいくつかのテストを行いました。各テストはすべてのクリーンに対して実行されます(de/glaucheは両方のマシンとネクサスから削除されます)
- MVN Deployを使用してMaven 2.2.1:
マシンAのローカルリポジトリにはsnapshot.jar + snapshot-timestamp.jarが含まれています
ただし、Nexusにあるタイムスタンプ付きジャーは1つだけ、メタデータは次のように読みます。
<?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(組み込みM3ファイナル)の更新依存関係(マシンB)を実行します - >ローカルリポジトリにはsnapshot.jar + snapshot -timestamp.jar :(
- 外部Mavenでパッケージ目標を実行する2.2.1->ローカルリポジトリにはsnapshot.jar + snapshot -timestamp.jar :(
OK、次にMaven 3.0.1で試してみてください(プロジェクトaのすべてのトレースを削除した後)
マシンのローカルリポジトリAはよりよく見えます、1つのタメスタンプされていない瓶は1つだけです
Nexusのタイムスタンプ付きジャーのみが、メタデータが読みます:
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(組み込みM3ファイナル)の更新依存関係(マシンB)を実行します - >ローカルリポジトリにはsnapshot.jar + snapshot -timestamp.jar :(
外部Mavenでパッケージ目標を実行する2.2.1->ローカルリポジトリにはsnapshot.jar + snapshot -timestamp.jar :(
したがって、要約すると、Maven3の「展開」目標は2.2.1よりもうまく機能し、作成マシンのローカルリポジトリはうまく見えます。しかし、レシーバーは常に多くのタイムされたバージョンで終わります...
私は何が間違っているのですか?
更新3
また、他のさまざまな構成をテストしました。まず、NexusをArtifactory->同じ動作に置き換えました。次に、Linux Maven 3クライアントを使用して、リポジトリマネージャーからスナップショットをダウンロードします - >ローカルリポジトリにはまだタイムスタンプのスナップショットがあります:(
解決
<uniqueVersion>
(MVN展開を介して)dexusなどのMavenリポジトリに展開されたアーティファクトに適用される構成。
これらをNexusから削除するには、自動化されたジョブを簡単に作成して、毎日スナップショットリポジトリをパージできます。一定数のシップショットを保持するか、一定期間保持するように構成できます。その非常に簡単で、うまく機能します。
開発者マシンのローカルリポジトリのアーティファクトは、「インストール」の目標から到達し、これらのタイムスタンプを使用しないでください...リビジョン番号も増加しない限り、1つのスナップショットバージョンを置き換え続けます(例:1.0.0-- 1.0.1-Snapshotにスナップショット)。
他のヒント
このプラグインは、Projectのアーティファクトをローカルリポジトリから削除します。大規模なローカルスナップショットのコピーを1つだけ保持するのに役立ちます。
<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>
まあ、私は提案されたソリューションのどれも気に入らなかった。 Mavenキャッシュを削除すると、多くの場合、ネットワークトラフィックが大幅に増加し、ビルドプロセスが遅くなります。 Build-Helper-Maven-Pluginは1つのアーティファクトのみを支援します。私は、1つの簡単なコマンドで、ローカルキャッシュからすべての古いタイムスタンプのスナップショットアーティファクトをパージできるソリューションを望んでいました。数日間検索した後、私はあきらめて、小さなプログラムを書くことにしました。最終プログラムは、私たちの環境で非常にうまく機能しているようです。そこで、私はそれをそのようなツールを必要とするかもしれない他の人と共有することにしました。ソースはGithubから引き出すことができます: https://github.com/nadestin/tools/tree/master/mavencachecleanup
これのリモートリポジトリに関しては、通常の間隔でのスナップショットのパージを議論する以前の回答が機能すると思います。しかし、あなたの質問のローカル開発ワークステーション同期の一部に誰も取り組んでいません。
まだMaven3の使用を開始していないため、スナップショットがローカルマシンに蓄積し始めていることはまだありません。
しかし、M2eclipseにはさまざまな問題がありました。 「ワークスペース解像度」が有効になり、プロジェクトがワークスペース内に存在する場合、ソースの更新は通常、出血のエッジを保ちます。しかし、M2Eclipseが最近公開されたNexusで自分自身を更新することは非常に困難であることがわかりました。私たちはチーム内で同様の問題を経験していますが、非常に大きなプロジェクトグラフがあるため、特に問題があります。ワークスペースにはないが、頻繁にスナップショットを公開する依存関係がたくさんあります。
これは、Snapshotsを正確に処理しないM2eclipseの問題に戻ると確信しています。 Eclipse内のMavenコンソールでは、M2Eclipseがキャッシュバージョンを持っているために最近公開されたスナップショットの更新をスキップしていると言っていることがわかります。実行構成またはコマンドラインから-Uを実行する場合、 メイベン メタデータの変更を拾います。しかし、「更新スナップショット...」の選択は、M2Eclipseがこのキャッシュを期限切れにするようにM2Eclipseを指示するはずです。渡されているようには見えません。あなたがそれに投票することに興味があるなら、これに提出されたバグがそこにあるように見えます:https://issues.sonatype.org/browse/mngeclipse-2608
あなたはどこかでコメントでこれについて言及しました。
この問題の最善の回避策は、M2eclipse内から物事が崩壊し始めたときに、開発者にローカルワークステーションをパージさせることです。異なる問題に対する同様の解決策...他の人は、Maven 2.2.1および3のバッキングM2eclipseの問題を報告しており、私は同じことを見てきました。
Maven3を使用している場合は、最新のスナップショットのみを引くように構成し、リポジトリが言う時間の間(または手で期限切れになるまで)キャッシュできることを願っています。うまくいけば、地元のリポジトリにあるスナップショットがたくさんある必要がないことを願っています。
それは、あなたが手動で行っているビルドサーバーについて話しているのでない限りです mvn install
それらの上に。スナップショットがビルドサーバーのような環境上に構築されるのを防ぐ方法に関しては、各ビルドに独自のワークスペースとローカルリポジトリを使用することで、その弾丸をかわしました(ただし、Maven 2.2.1では、特定のものなどPOMSは常に〜/.M2/リポジトリから出てくるようです)余分なスナップショットは本当に単一のビルドのためだけに固執するだけで、それらはドロップされます(そしてゼロから再びダウンロードされます)。したがって、このアプローチは、そもそもより多くのスペースを食べることになりますが、すべてが単一のリポジトリから解決されるよりも安定したままになる傾向があります。このオプション(ハドソン上)は「Private Mavenリポジトリの使用」と呼ばれ、Mavenでビルドするために選択したときにプロジェクト構成のビルドセクションの高度なボタンの下にあります。そのオプションのヘルプ説明は次のとおりです。
通常、HudsonはMavenによって決定されたローカルMavenリポジトリを使用します - 正確なプロセスは文書化されていないようですが、それは〜/.m2/リポジトリであり、〜/.m2/settings.xmlでオーバーライドできます(詳細については参照を参照してください。)これは通常、同じノードで実行されるすべてのジョブが単一のMavenリポジトリを共有することを意味します。これの利点は、ディスクスペースを保存できることですが、これの欠点は、それらのビルドが互いに干渉する場合があることです。たとえば、POMのリポジトリがどれも持っていないという事実にもかかわらず、ローカルリポジトリにすべての依存関係を持っているという理由だけで、ビルドが誤って成功することになる可能性があります。
また、同じローカルリポジトリを使用しようとする同時のMavenプロセスを持つことに関するいくつかの問題があります。
このオプションがチェックされると、ハドソンはMavenに$ workspace/.repositoryをローカルMavenリポジトリとして使用するように指示します。これは、各ジョブがそれ自体のためだけに独自の孤立したMavenリポジトリを取得することを意味します。追加のディスクスペース消費を犠牲にして、上記の問題を修正します。
このオプションを使用する場合は、Maven Artifact Managerのセットアップを検討して、リモートMavenリポジトリを頻繁にヒットする必要がないようにしてください。
Hudsonで実行されたすべてのMavenジョブでこのモードをアクティブにしたい場合は、ここで説明する手法を参照してください。
これが役立つことを願っています - それがあなたの問題に対処しないならば、私がどこで見逃したかを教えてください。
グルーヴィーで, 、ようなタイムスタンプのファイルを削除します artifact-0.0.1-20101204.150527-6.jar
非常にシンプルにすることができます:
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()
}
}
インストール グルーヴィー, 、スクリプトをファイルに保存し、毎週実行をスケジュールし、あなたに合ったものは何でも、ログオンを開始します。
または、実行をmavenビルドに配線することもできます。 gmavenplus-plugin. 。 Mavenによってプロパティに設定されたリポジトリの場所はどのようにありますか settings.localRepository
そして、構成を変数にバインドします 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>
POMファイルに次のパラメーターを追加します
ポン
<configuration>
<outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename>
</configuration>
https://maven.apache.org/plugins/maven-dependency-plugin/copy-mojo.html
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>
Jenkinsで構成:
// copy artifact
copyMavenArtifact(artifact: "commons-collections:commons-collections:3.2.2:jar", outputAbsoluteArtifactFilename: "${pwd()}/target/my-folder/commons-collections.jar")