在调用gradle idea
时,相对于本地Jar包含,首先在类路径中对外部依赖项进行排序。因此:
dependencies {
compile fileTree(dir: 'libs', include:['*.jar'])
compile group: 'foo', name:'bar', version:'1.0.0'
}
最后将包括我的本地罐子。这是我项目中的问题,因为这些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是非常可定制的,但是对于我来说,这是一个很新的尝试,使失败。如何进行?
答案 0 :(得分:1)
我不是定期使用IntelliJ,而是在此问题的上下文中进行了尝试,我的印象是gradle的idea
插件和IntelliJ的gradle插件不能很好地配合使用。那就是您应该使用idea
gradle插件并将其导入为纯Java项目,或者使用IntelliJ的gradle插件将其导入为gradle项目。主要原因是idea
插件和IntelliJ插件生成的iml文件略有不同(这些文件保存了项目依赖关系,其中包括其他内容),这在将两个插件一起使用时会引起很多混乱。当您特别要求gradle idea
插件时,我使用了此插件并将其作为纯Java项目导入到IntelliJ中。
但是要回答您的问题,我发现没有证据表明在使用dependencies
存储库时,类路径上的库顺序与gradle文件的flatDir
部分中声明的顺序不同。使用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
文件夹中,有两个jars aaa-0.0.0.jar
和zzz-0.0.0.jar
都是guava-24.0-jre.jar
的副本。那就是两个罐子中都存在所有番石榴类。由于zzz:zzz-0.0.0
是gradle文件中的第一个依赖项,因此可以预期是从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中的外部依赖项列表没有显示本地库。更令人困惑的是,库是按字母顺序排列的,并且没有在类路径上反映出实际的顺序,这可能会造成很大的混乱:
要获取类路径上元素的实际顺序,您必须在模块设置(“打开模块设置”>“项目”>“模块”>“依赖项选项卡”)中的“模块依赖项”部分中查找这个:
如您所见,依赖项以正确的顺序列出,并且还包括本地库。此对话框中的库顺序与生成的iml文件中的顺序基本相同。
当使用IntelliJ gradle插件而不是gradle的idea
插件时,IntelliJ的行为基本相同,但是生成的iml文件看起来有所不同,并且外部库以不同的格式显示。但是在类路径顺序上没有区别。