89

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

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

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

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

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

現在、次の可能な解決策が表示されます。

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

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

アップデート:

動作を確認し、詳細情報を提供するために、小さな nexus サーバーをセットアップし、2 つのプロジェクト (a と 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>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

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

大量のスナップショットが構築される環境 (ハドソン サーバーを考えてください...) では、ローカル リポジトリが古いバージョンですぐにいっぱいになります

更新 2:

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

  • mvn deploy with maven 2.2.1 :

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

BUT: nexus にはタイムスタンプ付きの 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最終)で(マシンBで)更新依存関係を実行します->ローカルリポジトリにはsnapshot.jar + snapshot-timestamp.jarがあります:(
  • 外部maven 2.2.1でパッケージの目標を実行します->ローカルリポジトリにはsnapshot.jar + snapshot-timestamp.jarがあります:(

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

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

  • nexus にタイムスタンプ付きの jar が 1 つだけある場合、メタデータは次のように読み取ります。

    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

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

4

6 に答える 6

37

<uniqueVersion>Nexus などの Maven リポジトリに (mvn deploy を介して) デプロイされたアーティファクトに適用される構成 。

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

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

于 2010-12-01T18:36:25.853 に答える
15

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

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

于 2013-07-08T07:02:54.363 に答える
2

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

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

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

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

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

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

Maven3 を使用している場合は、最新の SNAPSHOT のみをプルするように構成し、リポジトリが指定する時間 (または手動で有効期限が切れるまで) キャッシュすることができることを願っています。そうすれば、ローカル リポジトリに多数の 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 成果物マネージャーをセットアップすることを検討してください。

Hudson で実行されるすべての Maven ジョブでこのモードを有効にしたい場合は、ここで説明する手法を参照してください。

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

于 2011-01-18T23:11:47.660 に答える
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>  
于 2015-01-23T12:13:05.923 に答える
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")
于 2016-07-26T21:28:25.013 に答える