如何在调用gradleidea时将本地依赖放在首位?
How to put local dependencies first when calling gradle idea?
当调用 gradle idea
时,相对于本地 Jar 包含,外部依赖项在 class 路径中排在第一位。因此:
dependencies {
compile fileTree(dir: 'libs', include:['*.jar'])
compile group: 'foo', name:'bar', version:'1.0.0'
}
将最后包含我的本地 jars。这是我项目中的一个问题,因为这些 jar 的目的是部分覆盖外部库。
使用 flatDir
将存储库指定为依赖项源并在不使用 fileTree
的情况下加载 jar 时,会观察到相同的行为。它放在 class 路径的最后。
我在研究时发现了几个提到的问题,例如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 中。
但是为了回答您的问题,我没有发现 class 路径上库的顺序与 gradle 文件的 dependencies
部分中声明的顺序不同的证据,使用 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
文件夹中有两个 jar aaa-0.0.0.jar
和 zzz-0.0.0.jar
都是 guava-24.0-jre.jar
的副本。这就是所有 guava classes 都存在于两个罐子中。由于 zzz:zzz-0.0.0
是 gradle 文件中的第一个依赖项,因此预期是从 zzz-0.0.0.jar
而不是 guava-24.0-jre.jar
或 aaa-0.0.0.jar
。我使用以下主要 class 来测试这个:
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
class 确实是从本地加载的 libs/zzz-0.0.0.jar
而不是 guava-24.0-jre.jar
.
我注意到 IntelliJ 中的外部依赖列表没有显示本地库。更令人困惑的是,这些库是按字母顺序排列的,并没有反映 class 路径上的实际顺序,这可能会让人非常困惑:
要获得 class 路径上元素的实际顺序,您必须查看模块设置中的模块依赖项部分 ("Open Module Settings" > "Project" > "Modules" > "Dependencies Tab") 看起来像这样:
如您所见,依赖项以正确的顺序列出,并且还包括本地库。此对话框中库的顺序与生成的 iml 文件中的顺序基本相同。
当使用 IntelliJ gradle 插件而不是 gradle 的 idea
插件时,IntelliJ 的行为基本相同,但生成的 iml 文件看起来不同并且外部库是以不同的格式显示。但是 class 路径顺序没有区别。
当调用 gradle idea
时,相对于本地 Jar 包含,外部依赖项在 class 路径中排在第一位。因此:
dependencies {
compile fileTree(dir: 'libs', include:['*.jar'])
compile group: 'foo', name:'bar', version:'1.0.0'
}
将最后包含我的本地 jars。这是我项目中的一个问题,因为这些 jar 的目的是部分覆盖外部库。
使用 flatDir
将存储库指定为依赖项源并在不使用 fileTree
的情况下加载 jar 时,会观察到相同的行为。它放在 class 路径的最后。
我在研究时发现了几个提到的问题,例如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 中。
但是为了回答您的问题,我没有发现 class 路径上库的顺序与 gradle 文件的 dependencies
部分中声明的顺序不同的证据,使用 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
文件夹中有两个 jar aaa-0.0.0.jar
和 zzz-0.0.0.jar
都是 guava-24.0-jre.jar
的副本。这就是所有 guava classes 都存在于两个罐子中。由于 zzz:zzz-0.0.0
是 gradle 文件中的第一个依赖项,因此预期是从 zzz-0.0.0.jar
而不是 guava-24.0-jre.jar
或 aaa-0.0.0.jar
。我使用以下主要 class 来测试这个:
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
class 确实是从本地加载的 libs/zzz-0.0.0.jar
而不是 guava-24.0-jre.jar
.
我注意到 IntelliJ 中的外部依赖列表没有显示本地库。更令人困惑的是,这些库是按字母顺序排列的,并没有反映 class 路径上的实际顺序,这可能会让人非常困惑:
要获得 class 路径上元素的实际顺序,您必须查看模块设置中的模块依赖项部分 ("Open Module Settings" > "Project" > "Modules" > "Dependencies Tab") 看起来像这样:
如您所见,依赖项以正确的顺序列出,并且还包括本地库。此对话框中库的顺序与生成的 iml 文件中的顺序基本相同。
当使用 IntelliJ gradle 插件而不是 gradle 的 idea
插件时,IntelliJ 的行为基本相同,但生成的 iml 文件看起来不同并且外部库是以不同的格式显示。但是 class 路径顺序没有区别。