maven-3のタイムスタンプ付きスナップショットを効率的に処理するにはどうすればよいですか?


87

maven-3がスナップショットアーティファクトの<uniqueVersion> false </ uniqueVersion>のサポートを終了したため、タイムスタンプ付きのSNAPSHOTSを実際に使用する必要があるようです。特に、内部でmaven 3を使用するm2eclipseは影響を受けているようですが、SNAPSHOTSが一意でない場合、update-snapshotsは機能しません。

以前は、すべてのスナップショットをuniqueVersion = falseに設定するのがベストプラクティスのようでした。

現在、タイムスタンプ付きバージョンに切り替えることは大きな問題ではないようです。結局、それらは中央のネクサスリポジトリによって管理されており、定期的な間隔で古いスナップショットを削除できます。

問題は、ローカルの開発者ワークステーションです。彼らのローカルリポジトリは、ユニークなスナップショットですぐに非常に大きくなります。

この問題に対処する方法は?

今、私は次の可能な解決策を見ています:

  • 開発者に定期的にリポジトリを削除するように依頼します(削除に時間がかかり、必要なものすべてをダウンロードするのにさらに時間がかかるため、多くのフラストレーションが発生します)
  • ローカルリポジトリからすべてのSNAPSHOTディレクトリを削除するスクリプトを設定し、開発者にそのスクリプトを時々実行するように依頼します(最初のスクリプトよりも優れていますが、現在のスナップショットの実行とダウンロードにはかなりの時間がかかります)
  • 依存関係:purge-local-repositoryプラグインを使用します(ファイルが開いているため、Eclipseから実行すると問題が発生し、各プロジェクトから実行する必要があります)
  • すべてのワークステーションにネクサスをセットアップし、古いスナップショットをクリーンアップするジョブをセットアップします(最良の結果ですが、50以上のネクサスサーバーを維持したくありません。さらに、開発者のワークステーションではメモリが常に不足しています)
  • SNAPSHOTSの使用を完全に停止します

ローカルリポジトリがハードドライブのスペースをいっぱいにしないようにするための最良の方法は何ですか?

更新:

動作を確認し、より多くの情報を提供するには、小さなネクサスサーバーをセットアップし、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」で「deploy」を実行すると、次のようになります。

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

ローカルリポジトリ内。デプロイターゲットを実行するたびに、新しいタイムスタンプバージョンを使用します。ネクサスサーバーからスナップショットを更新しようとすると同じことが起こります(「a」プロジェクトを閉じ、ローカルリポジトリから削除し、「b」をビルドします)

スナップショットの多くはビルドを取得する環境では(ハドソンサーバー...と思う)、ローカルreposiotyは、古いバージョンでいっぱいに速いです

アップデート2:

これが失敗する方法と理由をテストするために、さらにいくつかのテストを行いました。各テストは、すべてをクリーンにするために実行されます(de / glaucheはマシンとネクサスの両方から削除されます)

  • mvnはmaven2.2.1でデプロイします:

マシンAのローカルリポジトリには、snapshot.jar + snapshot-timestamp.jarが含まれています

しかし、ネクサスにはタイムスタンプ付きのjarが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 final)で(マシンBで)更新依存関係を実行します->ローカルリポジトリにはsnapshot.jar + snapshot-timestamp.jarがあります:(
  • 外部Maven2.2.1でパッケージゴールを実行します->ローカルリポジトリにはsnapshot.jar + snapshot-timestamp.jarがあります:(

OK、次にmaven 3.0.1で試してください(プロジェクトaの痕跡をすべて削除した後)

  • マシンAのローカルリポジトリの方が見栄えが良く、タイムスタンプのないjarファイルが1つだけです。

  • ネクサス内のタイムスタンプ付きのjarは1つだけで、メタデータは次のようになります。

    de.glauche a0.0.1-スナップショット

    <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 final)で(マシンBで)更新依存関係を実行します->ローカルリポジトリにはsnapshot.jar + snapshot-timestamp.jarがあります:(

  • 外部Maven2.2.1でパッケージゴールを実行します->ローカルリポジトリにはsnapshot.jar + snapshot-timestamp.jarがあります:(

したがって、要約すると、maven3の「デプロイ」目標は2.2.1よりもうまく機能し、作成マシンのローカルリポジトリは正常に見えます。しかし、レシーバーは常に多くのタイムステイドバージョンで終わります...

私は何が間違っていますか?

アップデート3

また、他のさまざまな構成もテストしました。最初に、ネクサスをアーティファクト->同じ動作に置き換えました。次に、linux maven 3クライアントを使用して、リポジトリマネージャーからスナップショットをダウンロードします->ローカルリポジトリにはまだタイムスタンプ付きのスナップショットがあります:(


(Jenkins)ビルドサーバー上のローカルリポジトリに焦点を当てた、ローカルの.m2 \ repository部分のみに関する関連質問:stackoverflow.com/q/9729076/223837
MarnixKlooster ReinstateMonica 2014

-ここでApcahe MavenのComptabilityノートへのリンク取り組んでいるcwiki.apache.org/confluence/display/MAVEN/...
aka_sh

回答:


36

<uniqueVersion>コンフィギュレーションは、ネクサスとしてのMavenリポジトリに(MVN配布を介して)展開された成果物に適用されます。

これらをNexusから削除するには、自動ジョブを簡単に作成して、SNAPSHOTリポジトリを毎日削除できます。特定の数のシャップショットを保持するか、特定の期間保持するように構成できます。その超簡単で素晴らしい働きをします。

開発者マシンのローカルリポジトリ内のアーティファクトは、「インストール」の目標からそこに到達し、これらのタイムスタンプを使用しません...リビジョン番号もインクリメントしない限り、唯一のSNAPSHOTバージョンを置き換え続けるだけです(例:1.0.0- SNAPSHOTから1.0.1-SNAPSHOT)。


1
問題は、「インストール」の目標が、多くの開発者がいる分散環境ではあまり使用されないことです。また、cvsコミットごとに新しいスナップショットをビルド(およびデプロイ)するハドソンサーバーを使用します。これは毎日非常に頻繁に発生します。ネクサススナップショット削除mechainsmについて知っていました。可能な回避策のリストを参照してください。
mglauche 2010

各開発マシンには「ローカル」リポジトリが~/.m2/repositoryあり、それぞれにpom.xmlLAN上のNexusの単一インスタンスを指すリポジトリ定義が必要です。(あなたが示すように)。すべてのSubversionコミットに基づいて構築されたHudsonとともに、このセットアップがあり、うまく機能します。SNAPSHOTビルドはNexusに「デプロイ」され、そこで収集され、毎週パージされます。開発者のマシンは、最新のスナップショットをNexusからに自動的にダウンロードし ~/.m2/repository、以前にダウンロードしたものを置き換えます。開発者は、独自のNexusインスタンスを持つべきではありません。
HDave 2010

2
更新を読んだだけで、もう1つ追加することがあります。タイムスタンプ付きのアーティファクトがローカル(〜/ .m2 / repository)リポジトリ内に表示されないようにする必要があります。もしそうなら、何かが間違っています。それらはNexusの内部でのみ表示されます。Nexusの内部では、はい、すぐに収集されます。潜在的に1日数百MB。ネクサスジョブは、これらを毎日簡単にパージして、量を少なく保つことができます。
HDave 2010

6
それらは間違いなくローカルリポジトリ(〜/ .m2 / repositoryリポジトリ)に配置され、「デプロイ」ターゲット実行し、依存するプロジェクト(つまりBプロジェクト)にmvn-Uをインストールした後に終了します。Maven2.2.1とMaven3でテストしたこともありますが、どちらも同じ動作をします。
mglauche 2010

2
私は今それを手に入れていると思います...開発者が「デプロイ」を行うときではなく、開発者が依存プロジェクトをビルドするときに表示されます。その時点で、アップストリームプロジェクトの最新のSNAPSHOTがNexusから〜/ .m2 / repositoryにダウンロードされ、タイムスタンプはファイル名の一部としてそのまま残されます。これは正解?
HDave 2010

14

このプラグインは、プロジェクトのアーティファクトをローカルリポジトリから削除します。大規模なローカルスナップショットのコピーを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>

7

さて、私は提案された解決策のどれも好きではありませんでした。Mavenキャッシュを削除すると、多くの場合、ネットワークトラフィックが大幅に増加し、ビルドプロセスが遅くなります。build-helper-maven-pluginは1つのアーティファクトでのみ役立ちます。1つの簡単なコマンドでローカルキャッシュからすべての古いタイムスタンプ付きスナップショットアーティファクトをパージできるソリューションが必要でした。数日検索した後、私はあきらめて小さなプログラムを書くことにしました。最終的なプログラムは、私たちの環境で非常にうまく機能しているようです。そこで、そのようなツールが必要な他の人と共有することにしました。ソースはgithubから取得できます:https//github.com/nadestin/tools/tree/master/MavenCacheCleanup


@HDaveここでpomフラグメントを適切にフォーマットできませんでした。https://github.com/nadestin/tools/wiki/m2cachecleanup-maven-pluginで確認してください。Jenkinsスレーブでは、このユーティリティは毎日最大200Mbのディスクスペースを再利用します。
yurinadestin 2013

2

これのリモートリポジトリ部分に関しては、定期的な間隔でのスナップショットのパージについて説明した以前の回答が機能すると思います。しかし、あなたの質問のローカル開発者ワークステーション同期の部分に誰も取り組んでいません。

Maven3の使用はまだ開始されていないため、SNAPSHOTがローカルマシン上に構築され始めているのはまだ確認されていません。

しかし、m2eclipseにはさまざまな問題がありました。「ワークスペース解決」を有効にしていて、プロジェクトがワークスペース内に存在する場合、通常、ソースの更新により最先端の状態が維持されます。しかし、Nexusで最近公開されたアーティファクトでm2eclipseを更新するのは非常に難しいことがわかりました。チーム内でも同様の問題が発生しています。プロジェクトグラフが非常に大きいため、特に問題があります。ワークスペースにはない依存関係がたくさんありますが、SNAPSHOTが頻繁に公開されます。

これは、m2eclipseの問題に帰着すると確信しています。この問題では、SNAPSHOTが適切に処理されません。Eclipse内のMavenコンソールで、m2eclipseが、キャッシュされたバージョンを持っているため、最近公開されたSNAPSHOTの更新をスキップしていることを通知していることがわかります。実行構成またはコマンドラインから-Uを実行すると、Mavenはメタデータの変更を取得します。ただし、「スナップショットの更新...」を選択すると、Mavenがこのキャッシュを期限切れにするようにm2eclipseに指示する必要があります。受け継がれているようには見えません。あなたがそれに投票することに興味があるなら、これのために提出されたバグがあるようです:https//issues.sonatype.org/browse/MNGECLIPSE-2608

あなたはどこかのコメントでこれについて言及しました。

この問題の最善の回避策は、m2eclipse内から問題が発生し始めたときに、開発者にローカルワークステーションをパージさせることです。別の問題に対する同様の解決策...他の人がMaven2.2.1および3バッキングm2eclipseの問題を報告しており、私も同じことを見てきました。

Maven3を使用している場合は、最新のSNAPSHOTのみをプルするように構成し、リポジトリが指定する時間(または手動で期限切れになるまで)キャッシュすることができれば幸いです。うまくいけば、ローカルリポジトリに多数のスナップショットを配置する必要はありません。

それは、手動で実行しているビルドサーバーについて話している場合を除きます。 mvn installそれらの上に。ビルドサーバーのような環境でSNAPSHOTがビルドされないようにする方法については、ビルドごとに独自のワークスペースとローカルリポジトリを使用することで、その弾丸をかわしました(ただし、Maven 2.2.1では、次のような特定のものがあります。 POMは常に〜/ .m2 / repositoryから出てくるようです)余分なSNAPSHOTは、実際には1つのビルドでのみ残り、その後ドロップされます(そして最初から再度ダウンロードされます)。したがって、このアプローチは最初からより多くのスペースを消費することになりますが、単一のリポジトリからすべてを解決するよりも安定したままになる傾向があります。このオプション(Hudson上)は「プライベートMavenリポジトリーを使用する」と呼ばれ、Mavenでビルドすることを選択した場合、プロジェクト構成の「ビルド」セクションの「詳細」ボタンの下にあります。そのオプションのヘルプの説明は次のとおりです。

通常、HudsonはMavenによって決定されたローカルMavenリポジトリを使用します—正確なプロセスは文書化されていないようですが、それは〜/ .m2 / repositoryであり、〜/ .m2 / settings.xmlでオーバーライドできます(詳細については、リファレンスを参照してください)。 。)これは通常、同じノードで実行されるすべてのジョブが単一のMavenリポジトリーを共有することを意味します。これの利点は、ディスクスペースを節約できることですが、これの欠点は、これらのビルドが互いに干渉する可能性があることです。たとえば、POMのどのリポジトリにも依存関係がない可能性があるにもかかわらず、ローカルリポジトリにすべての依存関係があるという理由だけで、ビルドが誤って成功する可能性があります。

並行Mavenプロセスが同じローカルリポジトリを使用しようとすることに関して、いくつかの問題が報告されています。

このオプションをオンにすると、HudsonはMavenに$ WORKSPACE /.repositoryをローカルのMavenリポジトリとして使用するように指示します。これは、各ジョブがそれ自体のためだけに独自の分離されたMavenリポジトリを取得することを意味します。追加のディスクスペース消費を犠牲にして、上記の問題を修正します。

このオプションを使用するときは、Mavenアーティファクトマネージャーをセットアップして、リモートのMavenリポジトリーに頻繁にアクセスする必要がないようにすることを検討してください。

ハドソンで実行されるすべてのMavenジョブでこのモードをアクティブにする場合は、ここで説明する手法を参照してください。

これがお役に立てば幸いです。問題が解決しない場合は、どこを見逃したか教えてください。


上記のバグが修正されました:bugs.eclipse.org/bugs/show_bug.cgi
id =

1

groovyでは、次のようなタイムスタンプ付きファイルの削除は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()
  }
}

Groovyをインストールし、スクリプトをファイルに保存して、毎週実行をスケジュールし、開始し、ログオンします。

または、gmavenplus-pluginを使用して、実行をmavenビルドにワイヤリングすることもできます。リポジトリの場所が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>  

0

次のパラメータをPOMファイルに追加します

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")
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.