如何从Maven存储库中清除旧的依赖项?


69

我在.m2文件夹中有太多文件,maven在那里存储了已下载的依赖项。有没有办法清除所有旧的依赖项?例如,如果某个依赖项具有3个不同的版本:1、2和3,则清理后必须只有3rd。我该如何处理.m2文件夹中的所有依赖项?


3
只需删除.m2repository文件夹。编译项目后,它将自动创建。
user2339071 2013年

3
或购买更大的硬盘,不在乎:)
smajlo

8
也许有比等待编译和花更多的钱来存储硬盘更好的解决方案?:)但是严重的是,我在虚拟机上远程工作,因此磁盘空间(较小)和编译时间(较长)非常重要。这就是为什么我不能简单地更换硬盘或处理器。因此,我需要一种更有效地使用它的方法。
樱桃,

如果您已打开IDE以及所有最近的项目,则文件系统锁将阻止您删除正在使用的jar
数字幻觉

如何通过pom文件清除依赖项?
Tushar Banne '16

Answers:


37

如果您使用的是Unix,则可以使用其中的文件访问时间。只需为文件系统启用访问时间,然后对要保留依赖关系的所有项目运行一个干净的构建,然后执行以下操作(未测试!):

find ~/.m2 -amin +5 -iname '*.pom' | while read pom; do parent=`dirname "$pom"`; rm -Rf "$parent"; done

这将查找所有最近一次访问超过5分钟的* .pom文件(假设您在5分钟前最多开始构建)并删除其目录。

在rm之前添加“ echo”以进行“空运行”。


17
在OSX上(也可以在GNU工具上使用) find ~/.m2/repository/ -atime +30 -iname '*.pom' -print0 | while read -d '' -r pom; do echo rm -rf "$(dirname $pom)"; doneatime以天为单位(相比,amin以分钟为单位)
布莱斯

2
find ~/.m2 -atime +1w -iname '*.pom' | while read pom; do parent=$(dirname "$pom"); rm -rf "$parent"; done我在OSX上使用适用于我的工具。应该也可以在其他Unix上正常工作:)
Meeh

我刚刚爱上了“发现”
乔纳斯·艾希

29

简短答案-已删除.m2文件夹{user.home}。例如在Windows 10用户家庭中为C:\Users\user1。使用重新构建您的项目mvn clean package。项目将只保留那些依赖项。

长答案-.m2文件夹就像普通文件夹一样,并且文件夹的内容是根据不同的项目构建的。我认为没有办法自动找出哪个库是“旧的”。实际上,old是一个模糊的词。在项目中使用库的先前版本时,可能有很多原因,因此无法确定哪个库未使用。

您所能做的就是删除.m2文件夹并重新构建所有项目,然后该文件夹将自动使用所有必需的库进行构建。

如果您只关心在所有项目中使用的特定版本的库,请关注;重要的是项目的pom也应该更新到最新版本。即,如果不同的POM引用了库的不同版本,则所有文件都将以.m2下载。


“由此确定哪一个是未使用是不可能的”我不需要这个决心我只需要离开新版本。
樱桃

2
然后删除.m2文件夹,然后确保所有项目在pom.xml中仅具有jar条目的新版本。重新生成项目。.m2文件夹将仅保留最新版本。
Gyanendra Dwivedi

1
delete .m2它导致删除所有依赖项并从存储库下载新的依赖项,这非常慢。
2015年

对于上述问题-一种适合所有人的解决方案-我们可以采用上述方法。对于速度慢的问题,我建议项目应咨询本地回购(组织中的产品存储库设置的种类);如果不可用,请从公共资源库下载。在某个时间点,建议将工件最终上传到本地存储库-如果它在所有项目中都得到了如此广泛的使用。
Gyanendra Dwivedi 2015年

18

给定一个Maven项目的POM文件,您可以使用Apache Maven Dependency Plugin删除其在本地存储库中的所有依赖项(默认为〜/ .m2 / respository)。

它包含的dependency:purge-local-repository功能可以从本地存储库中删除项目依赖项,并可以选择重新解析它们。

要清除本地依赖项,您仅需使用可选参数reResolve并将其设置为false,因为默认情况下将其设置为true。

此命令行调用应该工作:

mvn dependency:purge-local-repository -DreResolve=false

3
很好:)但是此清理仅取决于当前项目,而不是所有存储库。
樱桃

2
确实如此!为了清理整个存储库,我会手动进行操作,并按照.Nexus之前或在较新版本的Nexus(在2.6.4-02之后)中的说明从./m2/repository中删除目录,它们提供了计划任务 链接,从中删除从存储库发布版本盒子。它也可能有用
Juanjo Marron 2014年

5
  1. 下载项目的所有实际依赖项

    find your-projects-dir -name pom.xml -exec mvn -f '{}' dependency:resolve
    
  2. 将本地Maven存储库移动到临时位置

    mv ~/.m2 ~/saved-m2
    
  3. 将所有文件maven-metadata-central.xml *从保存的存储库重命名为maven-metadata.xml *

    find . -type f -name "maven-metadata-central.xml*" -exec rename -v -- 's/-central//' '{}' \;
    
  4. 要将修改后的本地存储库副本设置为镜像,请创建目录〜/ .m2和文件〜/ .m2 / settings.xml,其中包含以下内容(用用户名替换用户):

    <settings>
     <mirrors>
      <mirror>
       <id>mycentral</id>
       <name>My Central</name>
       <url>file:/home/user/saved-m2/</url>
       <mirrorOf>central</mirrorOf>
      </mirror>
     </mirrors>
    </settings>
    
  5. 再次解决您的项目依赖项:

    find your-projects-dir -name pom.xml -exec mvn -f '{}' dependency:resolve
    
  6. 现在,您有了本地的maven存储库,其中包含最少的必需工件。从配置文件和文件系统中删除本地镜像。


对此进行了尝试,但仍然得到:“在当前项目和存储库中[本地(/ home / user /.m2/repository),mycentral(file:/ home / user / saved-m2 /)]“
Robert Mikes

4

我想出了一个实用程序,并将其托管在GitHub上,以清理本地Maven存储库中的旧版本库。该实用程序在默认执行时会删除所有较旧版本的工件,仅保留最新版本。(可选)它可以删除所有快照,源,javadocs,并且在此过程中可以强制/排除组或工件。该跨平台还支持基于上次访问/下载日期的基于日期的删除。

https://github.com/techpavan/mvn-repo-cleaner


3

提出问题已经6年多了,但是我没有找到任何工具来清理我的存储库。所以我用python写了一个我自己,以摆脱旧的罐子。也许对某人有用:

from os.path import isdir
from os import listdir
import re
import shutil

dry_run = False #  change to True to get a log of what will be removed
m2_path = '/home/jb/.m2/repository/' #  here comes your repo path
version_regex = '^\d[.\d]*$'


def check_and_clean(path):
    files = listdir(path)
    for file in files:
        if not isdir('/'.join([path, file])):
            return
    last = check_if_versions(files)
    if last is None:
        for file in files:
            check_and_clean('/'.join([path, file]))
    elif len(files) == 1:
        return
    else:
        print('update ' + path.split(m2_path)[1])
        for file in files:
            if file == last:
                continue
            print(file + ' (newer version: ' + last + ')')
            if not dry_run:
                shutil.rmtree('/'.join([path, file]))


def check_if_versions(files):
    if len(files) == 0:
        return None
    last = ''
    for file in files:
        if re.match(version_regex, file):
            if last == '':
                last = file
            if len(last.split('.')) == len(file.split('.')):
                for (current, new) in zip(last.split('.'), file.split('.')):
                    if int(new) > int(current):
                        last = file
                        break
                    elif int(new) < int(current):
                        break
            else:
                return None
        else:
            return None
    return last


check_and_clean(m2_path)

它在.m2存储库中递归搜索,如果找到不同版本所在的目录,则会删除所有版本,但最新版本除外。

假设您的.m2回购中某处有以下树:

.
└── antlr
    ├── 2.7.2
    │   ├── antlr-2.7.2.jar
    │   ├── antlr-2.7.2.jar.sha1
    │   ├── antlr-2.7.2.pom
    │   ├── antlr-2.7.2.pom.sha1
    │   └── _remote.repositories
    └── 2.7.7
        ├── antlr-2.7.7.jar
        ├── antlr-2.7.7.jar.sha1
        ├── antlr-2.7.7.pom
        ├── antlr-2.7.7.pom.sha1
        └── _remote.repositories

然后,脚本删除了antlr的2.7.2版本,剩下的是:

.
└── antlr
    └── 2.7.7
        ├── antlr-2.7.7.jar
        ├── antlr-2.7.7.jar.sha1
        ├── antlr-2.7.7.pom
        ├── antlr-2.7.7.pom.sha1
        └── _remote.repositories

如果您正在使用的任何旧版本将被删除。可以使用Maven(或其他管理依赖项的工具)轻松恢复它。

您可以通过设置设置获取要删除内容的日志,而无需实际删除它dry_run = False。输出将如下所示:

update /org/projectlombok/lombok
1.18.2 (newer version: 1.18.6)
1.16.20 (newer version: 1.18.6)

这意味着,将删除lombok的1.16.20和1.18.2版本,并且将保持1.18.6不变。

该文件可以在我的github(最新版本)上找到。


1

我也想从我的Maven存储库中删除旧的依赖项。我本来只是想运行Florian的答案,但我想要的是可以一遍又一遍地运行而又不记得很长的linux代码段的东西,并且我想要一些具有可配置性的东西-更多的是程序,更少的unix命令链,因此我采用了基本思想,并将其放入了一个(相对较小的)Ruby程序中,该程序会根据旧的依赖项的上次访问时间删除它们。

它不会删除“旧版本”,但是由于您实际上可能有两个具有两个不同版本的依赖项的活动项目,所以无论如何我都不会做。而是像Florian的答案一样,它删除了最近未访问的依赖项。

如果您想尝试一下,可以:

  1. 造访 GitHub存储库
  2. 克隆存储库,或下载源
  3. (可选)检查代码以确保它不是恶意的
  4. bin/mvnclean

有一些选项可以覆盖默认的Maven存储库,忽略文件,设置阈值日期,但是您可以在GitHub的README中阅读这些选项。

在完成一些工作之后,我可能会在某个时候将其打包为Ruby gem,gem install mvnclean; mvnclean如果您已经安装并可以运行Ruby ,这将简化事务()。


很高兴听见。猜猜我应该把它变成一颗宝石。
Geoffrey Wiseman

看来我讲得太早了。我不知道这种模式-但是有些罐子被删除了,尽管我知道我最近用过它们。但是,与此同时,一些仍然存在。
catholicon 2015年

嗯 好吧,如果您能给我更多细节,我很乐意研究。如果您能做到这一点,请在GitHub上提交问题,以供我跟踪。似乎对我来说工作相当稳定,但是例如,我需要研究Cygwin的某些特定功能。您是否在同意之前查看了它输出的列表,还是太长以至于不值得审查?如果您确实想再尝试一次,如果我在摘要中添加了上次使用的日期,是否有帮助?(github.com/geoffreywiseman/mvnclean/issues/10
杰弗里威斯曼

是的,请确保您可以添加一些选项以转储调试输出(jar:最后访问日期)...我已经订阅了您打开的问题。
catholicon

更新; 看一下问题,介绍一些您的选择。
杰弗里·怀斯曼

1

只需清理.m2-> repository文件夹下的所有内容。构建项目时,所有依赖项都将加载到此处。

在您的情况下,您的项目可能先前使用的是任何依赖项的旧版本,而现在版本已升级。因此最好清理.m2文件夹并使用mvn clean install来构建项目。

现在,具有最新版本模块的依赖项将下载到此文件夹中。


2
除非您已将旧版jar手动添加到存储库中,否则Internet上不再提供依赖项。这个答案有点危险...至少要先备份!
何塞·曼努埃尔·戈麦斯·阿尔瓦雷斯

0

您需要复制项目所需的依赖项。掌握这些<dependency>标签后,请清除所有嵌入其中的标签<dependencies>项目中POM.XML文件中标签中的。

保存文件后,你将不会看到Maven依赖Libraries。那请贴上<dependency>您之前复制的内容。

所需的jar将由Maven自动下载,您也可以在生成的Maven Dependencies中看到 Libraries保存文件后。

谢谢。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.