当调用gradle idea
时,外部依赖项在类路径中相对于本地 Jar 包含首先排序。因此:
dependencies {
compile fileTree(dir: 'libs', include:['*.jar'])
compile group: 'foo', name:'bar', version:'1.0.0'
}
最后将包括我本地的 jar 。这是我的项目中的一个问题,因为这些 jar 的目的是部分覆盖外部库。
使用 flatDir
将存储库指定为依赖项源并在不使用 fileTree
的情况下加载 jar 时,会观察到相同的行为。它被放在类路径的最后。
我在研究时发现了几个提到这个问题的地方,例如https://discuss.gradle.org/t/gradle-messes-up-the-classpath-order-in-generated-projects-when-there-are-mixed-dependency-types/13130 ,但没有解决方法。
我想这些是存在的,gradle 是非常可定制的,但我对它很陌生,我的尝试失败了。如何进行?
最佳答案
我没有定期使用 IntelliJ,但在这个问题的背景下尝试过它,我的印象是 gradle 的 idea
插件和 IntelliJ 的 gradle 插件不能很好地结合在一起。也就是说,您应该使用 idea
gradle 插件并导入为普通 Java 项目,或者使用 IntelliJ 的 gradle 插件导入为 gradle 项目。主要原因是 idea
插件和 IntelliJ 插件生成的 IML 文件略有不同(这些文件包含项目依赖项等),这会在同时使用这两个插件时导致很多困惑。由于您特别要求使用 gradle idea
插件,我使用了该插件并将其作为纯 java 项目导入到 IntelliJ 中。
但是为了回答你的问题,我没有发现任何证据表明在使用 flatDir< 时,类路径上的库的顺序与 gradle 文件的
repo 协议(protocol)。当使用 dependency
部分中声明的顺序不同。/compile fileTree(dir: 'libs', include:['*.jar'])
时,顺序实际上被破坏了,如您的问题中所述。也就是说,您应该坚持使用 flatDir
存储库。
我使用的是 gradle 4.9 和 IntelliJ 2018.2。
这是我的 gradle 文件
apply plugin: 'java'
apply plugin: 'idea'
repositories {
jcenter()
flatDir {
dirs 'libs'
}
}
dependencies {
compile 'zzz:zzz-0.0.0'
compile 'aaa:aaa-0.0.0'
compile 'com.google.guava:guava:24.0-jre'
compile group: 'javax.websocket', name: 'javax.websocket-api', version: '1.1'
}
task wrapper(type: Wrapper) {
gradleVersion = '4.9'
distributionUrl = "http://services.gradle.org/distributions/gradle-${gradleVersion}-bin.zip"
}
在我的libs
文件夹中,有两个jar文件aaa-0.0.0.jar
和zzz-0.0.0.jar
都是副本guava-24.0-jre.jar
。也就是说,所有 Guava 类都存在于两个 jar 中。由于 zzz:zzz-0.0.0
是 gradle 文件中的第一个依赖项,因此预期 guava 类将从 zzz-0.0.0.jar
加载guava-24.0-jre.jar
或 aaa-0.0.0.jar
。我使用以下主类来测试这一点:
package test;
import com.google.common.math.LongMath;
public class Test {
public static void main(String[] args) throws Exception {
System.out.println(LongMath.class.getProtectionDomain().getCodeSource().getLocation().toURI());
}
}
从 IntelliJ 运行它时的输出是
文件:/C:/ws/gradle-idea-test/libs/zzz-0.0.0.jar
这就是 com.google.common.math.LongMath
类确实是从本地 libs/zzz-0.0.0.jar
加载的,而不是 guava-24.0-jre.jar
。
我注意到 IntelliJ 中的外部依赖项列表不显示本地库。更令人困惑的是,库按字母顺序排序,并没有反射(reflect)类路径上的实际顺序,这可能会非常令人困惑:
要获取类路径上元素的实际顺序,您必须查看模块设置中的模块依赖项部分(“打开模块设置”>“项目”>“模块”>“依赖项选项卡”),如下所示这个:
正如您所看到的,依赖项以正确的顺序列出,并且还包括本地库。该对话框中的库顺序与生成的 iml 文件中的顺序基本相同。
当使用 IntelliJ gradle 插件而不是 gradle 的 idea
插件时,IntelliJ 的行为方式基本相同,但生成的 iml 文件看起来不同,并且外部库以不同的格式显示。但类路径顺序没有区别。
关于java - 调用gradle idea时如何将本地依赖放在第一位?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51671037/