你如何有效地处理maven-3时间戳快照?

既然maven-3确实放弃了对快照制品的<uniqueVersion> false </ uniqueVersion>的支持,看起来你确实需要使用时间戳SNAPSHOTS。 特别是在内部使用maven 3的m2eclipse似乎受到了影响,当SNAPSHOTS不唯一时,update-snapshots不起作用。

将所有快照设置为uniqueVersion = false似乎是最佳做法

现在,切换到时间戳版本似乎没有什么大问题,毕竟他们是由一个中央连接库pipe理的,它可以在常规的intervalls中删除旧的快照。

问题是当地的开发人员工作站。 他们的本地存储库通过独特的快照迅速增长。

如何处理这个问题?

现在我看到以下可能的解决scheme:

  • 要求开发人员定期清除存储库(这会导致大量的篡改,因为删除需要很长时间,甚至需要更长时间才能下载)
  • 设置一些脚本,它会删除本地存储库中的所有SNAPSHOT目录,并要求开发人员不时运行该脚本(比第一个更好,但仍需要相当多的时间来运行和下载当前快照)
  • 使用依赖项:purge-local-repository plugin(从eclipse运行时,由于打开的文件,需要从每个项目运行)
  • 在每个工作站上build立连接,并build立一个工作来清理旧的快照(最好的结果,但我不想维护50 + nexus服务器,再加上开发工作站上的内存总是很紧张)
  • 停止使用SNAPSHOTS

保持本地存储库不会占用硬盘空间的最佳方法是什么?

更新:

为了validationbeaviour和给更多的信息我build立一个小的nexus服务器,build立两个项目(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-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服务器更新快照(closures“a”项目,将其从本地存储库中删除,构build“b”)时也会发生同样的情况

在许多快照获取构build的环境(想想哈德森服务器…),本地reposioty填满旧版本快速

更新2:

为了testing如何以及为什么这是失败,我做了一些更多的testing。 每个testing都是针对干净的东西运行的(de / glauche从机器和连接器中删除)

  • 用maven 2.2.1部署mvn:

机器A上的本地存储库包含snapshot.jar + snapshot-timestamp.jar

但是:在nexus中只有一个时间戳jar,元数据如下:

 <?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(embedded m3 final)上运行更新依赖关系(在机器B上) – >本地仓库有snapshot.jar + snapshot-timestamp.jar 🙁
  • 用外部maven运行包目标2.2.1 – >本地存储库有snapshot.jar + snapshot-timestamp.jar 🙁

好吧,接下来尝试使用maven 3.0.1(删除项目a的所有痕迹后)

  • 机器A上的本地存储库看起来更好,只有一个非时间戳的jar

  • 元数据中只有一个时间戳jar,元数据如下:

    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(embedded m3 final)上运行更新依赖关系(在机器B上) – >本地仓库有snapshot.jar + snapshot-timestamp.jar 🙁

  • 用外部maven运行包目标2.2.1 – >本地存储库有snapshot.jar + snapshot-timestamp.jar 🙁

因此,回顾一下:maven3中的“部署”目标比2.2.1更好,创build机器上的本地存储库看起来很好。 但是,接收机总是以很多时间版本结束

我究竟做错了什么 ?

更新3

我也做了其他各种configuration的testing,先用artifactoryreplacenexus – >相同的行为。 然后使用Linux Maven 3客户端从版本库pipe理器下载快照 – >本地存储库仍然有时间戳快照:(

<uniqueVersion>configuration应用于部署(通过mvn deploy)到Maven存储库(如Nexus)的工件。

要从Nexus中删除这些内容,您可以轻松创build一个自动化作业,以便每天清除SNAPSHOT存储库。 它可以被configuration为保留一定数量的shapshots或保持一段时间。 它超级简单,效果很好。

开发人员机器上的本地存储库中的工件从“安装”目标到达那里,不要使用这些时间戳记…他们只是继续replace唯一的SNAPSHOT版本,除非您还增加了修订版本号(例如1.0.0- SNAPSHOT到1.0.1-SNAPSHOT)。

这个插件从本地存储库中删除项目的工件。 有用的是只保留大型本地快照的一个副本。

 <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> 

那么我不喜欢任何提议的解决scheme。 删除mavencaching通常会显着增加networkingstream量并减慢构build过程。 build-helper-maven-plugin只能帮助一个工件,我想要一个解决scheme,可以用一个简单的命令从本地caching中清除所有过时的时间戳快照工件。 经过几天的search,我放弃了,决定写一个小程序。 最后的程序似乎在我们的环境中工作得很好。 所以我决定与其他可能需要这种工具的人分享。 来源可以从github: https : //github.com/nadestin/tools/tree/master/MavenCacheCleanup

就远程存储库而言,我认为先前讨论定期清除SNAPSHOT的答案是可行的。 但是没有人解决你的问题的本地开发者工作站同步部分。

我们还没有开始使用Maven3,所以我们还没有看到SNAPSHOT开始build立在本地机器上。

但是我们在m2eclipse上遇到了不同的问题。 当我们启用“工作空间解决scheme”并且项目存在于我们的工作空间内时,源代码更新通常会使我们处于最前沿。 但是我们发现使用最近发布的Nexus中的工件来更新m2eclipse是非常困难的。 我们在团队中遇到了类似的问题,因为我们有一个非常大的项目图表,有很多依赖项不会在您的工作区中,但会频繁地发布SNAPSHOTs。

我很确定这回滚到m2eclipse中的一个问题,它不能完全按照它应该处理SNAPSHOT。 你可以在eclipse中的Maven控制台中看到m2eclipse告诉你它跳过了最近发布的SNAPSHOT的更新,因为它有一个caching版本。 如果您从运行configuration或从命令行执行-U, Maven将select元数据更改。 但是“Update Snapshots …”选项应该告诉m2eclipse让Maven终止这个caching。 它似乎没有被传递。 如果你有兴趣投票的话,似乎有一个错误提交给你: https : //issues.sonatype.org/browse/MNGECLIPSE-2608

你在某处发表了评论。

对于这个问题,最好的解决方法似乎是让开发人员在m2eclipse内部开始分解时清除本地工作站。 类似的解决scheme不同的问题…其他人已经报告了Maven 2.2.1和3支持m2eclipse的问题,我也看到了相同的问题。

我希望,如果你使用的是Maven3,你可以configuration它只提取最新的SNAPSHOT,并将其caching到存储库所说的时间量(或者直到你手动过期)。 希望你不需要在你的本地仓库中有一堆SNAPSHOT。

这是除非你正在谈论一个构build服务器,手动进行mvn install 。 至于如何防止SNAPSHOTbuild立在像构build服务器这样的环境上,我们通过让每个构build都使用自己的工作空间和本地存储库(尽pipe在Maven 2.2.1中,某些东西如POM似乎总是从〜/ .m2 / repository中出来)额外的SNAPSHOTs确实只是为了一个单独的构build而存在,然后被丢弃(并从头开始再次下载)。 所以我们已经看到,这种方法最终会占用更多的空间,但它比单个存储库中的所有内容都更加稳定。 这个选项(在Hudson上)被称为“Use private Maven repository”,当你select使用Maven构build时,这个选项位于项目configuration的Build部分的Advancedbutton之下。 以下是该选项的帮助说明:

通常,Hudson使用Maven确定的本地Maven仓库 – 确切的过程似乎没有logging,但它是〜/ .m2 / repository,可以在〜/ .m2 / settings.xml中重写(参见参考资料以获取更多细节)这通常意味着在同一节点上执行的所有作业共享一个Maven存储库。 这样做的好处是可以节省磁盘空间,但是这样做的缺点是有时候这些构build会互相干扰。 例如,你可能最终会造成错误的成功,只是因为你拥有本地资源库中的所有依赖关系,尽pipePOM中没有一个资源库可能拥有它们。

还有一些报告的问题,有关并发Maven进程试图使用相同的本地存储库。

当选中这个选项时,Hudson会告诉Maven使用$ WORKSPACE / .repository作为本地的Maven仓库。 这意味着每个工作都会为自己获得自己的独立的Maven仓库。 它修复了上述问题,但是牺牲了额外的磁盘空间消耗。

使用这个选项时,考虑设置一个Maven工件pipe理器,这样你就不必经常打远程Maven仓库。

如果您希望在Hudson上执行的所有Maven作业中激活此模式,请参阅此处所述的技巧。

希望这有助于 – 如果它不解决您的问题,请让我知道我错过了什么。

在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 ,将脚本保存到一个文件中,并在每周安排执行,开始,login,无论你适合什么。

或者,甚至可以使用gmavenplus-plugin将执行连接到maven build。 请注意,如何通过maven将资源库位置设置到属性settings.localRepository ,然后通过configuration绑定到variablesrepository

  <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文件中

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中configuration:

 // copy artifact copyMavenArtifact(artifact: "commons-collections:commons-collections:3.2.2:jar", outputAbsoluteArtifactFilename: "${pwd()}/target/my-folder/commons-collections.jar")