惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
小众软件
小众软件
爱范儿
爱范儿
Y
Y Combinator Blog
博客园 - Franky
美团技术团队
博客园 - 【当耐特】
The Cloudflare Blog
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
Jina AI
Jina AI
IT之家
IT之家
人人都是产品经理
人人都是产品经理
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
大猫的无限游戏
大猫的无限游戏
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 聂微东
WordPress大学
WordPress大学
V
Visual Studio Blog
博客园_首页
阮一峰的网络日志
阮一峰的网络日志
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
有赞技术团队
有赞技术团队

二丫讲梵

学习周刊-总第258期-2026年第15周 学习周刊-总第257期-2026年第14周 学习周刊-总第256期-2026年第13周 学习周刊-总第255期-2026年第12周 学习周刊-总第254期-2026年第11周 学习周刊-总第253期-2026年第10周 临时插播一条羊毛,免费领取450元大模型API代金券 学习周刊-总第252期-2026年第09周 学习周刊-总第251期-2026年第08周 学习周刊-总第250期-2026年第07周 学习周刊-总第249期-2026年第06周 诚邀评论,聊聊你所知欲知的我 学习周刊-总第248期-2026年第05周 我的QQ动态之2015年 我的QQ动态之2014年 我的QQ动态之2013年 我的QQ动态之2012年 我的QQ动态-2010-2011年 我的QQ动态-创栏小叙 学习周刊-总第247期-2026年第04周 Nexus社区版权益阉割--一文告诉你有哪些版本可以选择 学习周刊-总第246期-2026年第03周 学习周刊-总第245期-2026年第02周 学习周刊-总第244期-2026年第01周 学习周刊-总第243期-2025年第52周 学习周刊-总第242期-2025年第51周 开源项目ZenOps:带你领略禅意运维 学习周刊-总第241期-2025年第50周 用京东金融,享负债人生 学习周刊-总第240期-2025年第49周
关于gradle中plugins依赖未走私服导致编译失败的原因探析
二丫讲梵 · 2023-06-04 · via 二丫讲梵

# 背景

我们的项目标配使用gradle进行编译,我们也配置了nexus作为私服,理论上来说,不应该再会出现因包依赖的原因导致编译失败的情况,但是这个问题仍旧会偶尔发生,我解决过一两次,只看到通常失败的编译都是在开头的时候去 plugins.gradle.org 拉包的情况,当时将该问题存疑,今天特来探析一下导致这个问题的根因。

# 摸索

简单分析: 理论上来说,当我们的gradle通过build.gradlerepositories指向私服地址之后,就不应该再出现任何一个第三方的私服地址才对,但 gradle 在这里就是异常头铁,偏偏会在开头请求一下官方地址。这是彼时遇到问题之后的一个原始的疑问!

缘起: 今天一位开发同学反馈说某项目在gray环境打包的时候出现编译失败的情况。我看到构建日志如下:

+ gradle --no-daemon bootJar

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring root project 'example'.
> Could not resolve all artifacts for configuration ':classpath'.
   > Could not resolve org.springframework.boot:spring-boot-gradle-plugin:2.1.5.RELEASE.
     Required by:
         project : > org.springframework.boot:org.springframework.boot.gradle.plugin:2.1.5.RELEASE
      > Could not resolve org.springframework.boot:spring-boot-gradle-plugin:2.1.5.RELEASE.
         > Could not parse POM https://plugins.gradle.org/m2/org/springframework/boot/spring-boot-gradle-plugin/2.1.5.RELEASE/spring-boot-gradle-plugin-2.1.5.RELEASE.pom
            > Could not resolve org.springframework.boot:spring-boot-tools:2.1.5.RELEASE.
               > Could not resolve org.springframework.boot:spring-boot-tools:2.1.5.RELEASE.
                  > Could not get resource 'https://plugins.gradle.org/m2/org/springframework/boot/spring-boot-tools/2.1.5.RELEASE/spring-boot-tools-2.1.5.RELEASE.pom'.
                     > Could not HEAD 'https://plugins.gradle.org/m2/org/springframework/boot/spring-boot-tools/2.1.5.RELEASE/spring-boot-tools-2.1.5.RELEASE.pom'.
                        > Remote host closed connection during handshake

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

通常遇到这种问题,我都会到对应构建的 Jenkins 服务器上,手动跑一次编译,然后 ci 机器再次打包就能过去了。这次使用同样手法将问题解决之后,我打算探究一下导致该问题的根因是什么。

后来了解到运维侧在打包的机器上有一个定时清理本地缓存的操作,是为了避免一些包依赖不更新的问题。所以当缓存清空之后,这些依赖就会重新下载,就可能因为网络原因而失败。

首先看到了报错提示的包基本都是 plugins,于是看了一眼 build.gradle 文件,可以看到在文件中有这样的配置声明:

plugins {
    id 'org.springframework.boot' version '2.1.5.RELEASE'
    id 'java'
}

1
2
3
4

报错的提示也正是在拉取该插件的时候报错的。

所以,这里得到一个问题是:即便已经配置指向了私服,但是此处的 plugins 中的包拉取的时候仍旧绕过了私服。

这是为什么呢?

通过 Google,找到了官方文档 (opens new window) 对 plugins 功能的介绍,并且里边也介绍了plugins 的仓库指向 (opens new window),需要通过单独的配置文件进行配置:

$ cat settings.gradle # 注意需要把配置文件放到这个文件的开头,而非build.gradle中
pluginManagement {
    repositories {
        maven {
            url './maven-repo'
        }
        gradlePluginPortal()
        ivy {
            url './ivy-repo'
        }
    }
}

1
2
3
4
5
6
7
8
9
10
11
12

这里我做了下测试,将如下配置添加到了项目对应的配置中:

$ cat settings.gradle
pluginManagement {
    repositories {
        //本地资源库
        mavenLocal()
        //自定义maven仓库
        maven {
            name 'aifocus-repository'
            url 'http://nexus.eryajf.net/nexus/content/groups/public/'
        }
    }
}

......

1
2
3
4
5
6
7
8
9
10
11
12
13
14

接着执行构建,发现如下报错:

FAILURE: Build failed with an exception.

* Where:
Build file '/data/gradle/example/build.gradle' line: 2

* What went wrong:
Plugin [id: 'org.springframework.boot', version: '2.1.5.RELEASE'] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (could not resolve plugin artifact 'org.springframework.boot:org.springframework.boot.gradle.plugin:2.1.5.RELEASE')
  Searched in the following repositories:
    MavenLocal(file:/root/.m2/repository)
    aifocus-repository(http://nexus.eryajf.net/nexus/content/groups/public/)

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 3s

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

在私服仓库中,找不到这个包,需要注意的是,虽然通过org.springframework.boot 能够搜索到包,但是这个包还有gradle.plugin的 path,所以如下检索到的包并不符合条件。

那么就需要将官方地址代理进来,此处要注意一个坑点在于,官方代理的正确地址是 https://plugins.gradle.org/m2/ 而非 https://plugins.gradle.org ,此处踩坑可见该帖子 (opens new window)

国内一些镜像库也有 plugin 的镜像,所以这里直接配置了阿里的镜像仓库:https://maven.aliyun.com/repository/gradle-plugin/

当我把官方地址加入到私服之后,再次回来进行构建,可以看到这个插件通过我们的私服进行拉取了,而正确拉取之后,私服当中也缓存了该依赖,符合预期,喜大普奔!

申明

原创文章eryajf,未经授权,严禁转载,侵权必究!此乃文中随机水印,敬请读者谅解。

# 结论

这个问题以后就变得简单了,所有使用 gradle 打包的项目,只要使用到了 plugins,那么就应该在 settings.gradle 文件的开头,加上如下配置:

pluginManagement {
    repositories {
        //本地资源库
        mavenLocal()
        //自定义maven仓库
        maven {
            name 'aifocus-repository'
            url 'http://nexus.eryajf.net/nexus/content/groups/public/'
        }
    }
}

1
2
3
4
5
6
7
8
9
10
11

从此不会再有与 plugins.gradle.org 这个域名交互的情况出现,自然也与编译失败说拜拜了!