为什么 Gradle 不使用插件 pom.xml 中声明的 Maven 存储库?
Why doesn't Gradle use Maven repositories declared in the plug-in's pom.xml?
假设我制作了一个自定义 Gradle 插件,可在 https://repo.example.com/xyz
获得并应用如下:
// build.gradle.kts
buildscript {
repositories {
jcenter()
maven("https://repo.example.com/xyz")
}
dependencies {
classpath("com.example:xyz-gradle-plugin:1.2.3")
}
}
apply(plugin = "com.example.xyz")
现在考虑我需要我的插件依赖于第三方库(org.something:abc:4.5.6
),它只能从另一个自定义 Maven 存储库(例如,https://repo.something.org/abc
).我相应地生成我的插件的 pom.xml
:
<dependencies>
<dependency>
<groupId>org.something</groupId>
<artifactId>abc</artifactId>
<version>4.5.6</version>
<scope>compile</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>xyz</id>
<url>https://repo.example.com/xyz/</url>
</repository>
<repository>
<id>abc</id>
<url>https://repo.something.org/abc/</url>
</repository>
</repositories>
现在,当我重建并重新发布插件时,使用它的客户端代码无法构建,因为找不到插件依赖的org.something:abc:4.5.6
库。显然,插件的 pom.xml
被误解了:从中提取了依赖信息,而 <repositories/>
部分被忽略了。
唯一的解决方法是将 maven("https://repo.something.org/abc")
显式添加到每个使用我的插件的项目的 buildscript
部分,我不想强迫我的用户这样做。
是否有其他解决方案?
更新: 这已作为 issue #8811.
报告给 Gradle 团队
引用 Gradle 团队的回复:
There are actually good reasons for the behavior of Gradle:
Gradle places a lot of importance on the source of a dependency. For Gradle, org:foo:1.0
from Maven Central and org:foo:1.0
from JCenter are considered different things. This is why repository ordering and filtering matters.
Repository hijacking has been demonstrated as an attack vector and so having a system that effectively, transitively and transparently, allows dependencies to be downloaded from any repository is not safe.
Because of these reasons, this is a change that is unlikely to happen.
There are however options for your plugin:
Shadow that exotic dependency into your own plugin
Motivate the owner of that library to publish it to a well known repository, or in your plugin's repository
Configure your plugin's repository to also mirror that other repository
假设我制作了一个自定义 Gradle 插件,可在 https://repo.example.com/xyz
获得并应用如下:
// build.gradle.kts
buildscript {
repositories {
jcenter()
maven("https://repo.example.com/xyz")
}
dependencies {
classpath("com.example:xyz-gradle-plugin:1.2.3")
}
}
apply(plugin = "com.example.xyz")
现在考虑我需要我的插件依赖于第三方库(org.something:abc:4.5.6
),它只能从另一个自定义 Maven 存储库(例如,https://repo.something.org/abc
).我相应地生成我的插件的 pom.xml
:
<dependencies>
<dependency>
<groupId>org.something</groupId>
<artifactId>abc</artifactId>
<version>4.5.6</version>
<scope>compile</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>xyz</id>
<url>https://repo.example.com/xyz/</url>
</repository>
<repository>
<id>abc</id>
<url>https://repo.something.org/abc/</url>
</repository>
</repositories>
现在,当我重建并重新发布插件时,使用它的客户端代码无法构建,因为找不到插件依赖的org.something:abc:4.5.6
库。显然,插件的 pom.xml
被误解了:从中提取了依赖信息,而 <repositories/>
部分被忽略了。
唯一的解决方法是将 maven("https://repo.something.org/abc")
显式添加到每个使用我的插件的项目的 buildscript
部分,我不想强迫我的用户这样做。
是否有其他解决方案?
更新: 这已作为 issue #8811.
报告给 Gradle 团队引用 Gradle 团队的回复:
There are actually good reasons for the behavior of Gradle:
Gradle places a lot of importance on the source of a dependency. For Gradle,
org:foo:1.0
from Maven Central andorg:foo:1.0
from JCenter are considered different things. This is why repository ordering and filtering matters.Repository hijacking has been demonstrated as an attack vector and so having a system that effectively, transitively and transparently, allows dependencies to be downloaded from any repository is not safe.
Because of these reasons, this is a change that is unlikely to happen.
There are however options for your plugin:
Shadow that exotic dependency into your own plugin
Motivate the owner of that library to publish it to a well known repository, or in your plugin's repository
Configure your plugin's repository to also mirror that other repository