Java 根据平台切换Gradle中的依赖项
我试图让Gradle在我的多项目构建中根据我是为桌面还是Android构建选择不同的依赖项。我有一个公共子项目(一个库),我正在尝试重用它。但是,我无法让Gradle正确切换依赖项配置 我的主要Java 根据平台切换Gradle中的依赖项,java,gradle,Java,Gradle,我试图让Gradle在我的多项目构建中根据我是为桌面还是Android构建选择不同的依赖项。我有一个公共子项目(一个库),我正在尝试重用它。但是,我无法让Gradle正确切换依赖项配置 我的主要设置。gradle仅包括所有依赖项: // /settings.gradle rootProject.name = 'myProject' include 'androidUI' include 'reusableLibrary' include 'desktopUI' 现在androidUI和des
设置。gradle
仅包括所有依赖项:
// /settings.gradle
rootProject.name = 'myProject'
include 'androidUI'
include 'reusableLibrary'
include 'desktopUI'
现在androidUI
和desktopUI
都将reusableLibrary
指定为依赖项:
// /androidUI/build.gradle and /desktopUI/build.gradle
apply plugin: 'java'
dependencies {
compile project(path: ':reusableLibrary', configuration: 'desktop')
}
reusableLibrary
本身指定了两种配置,因为无论是在桌面还是Android上构建,其依赖项都不同:
// /reusableLibrary/build.gradle
apply plugin: 'java'
configurations {
desktop {
extendsFrom compile
}
android {
extendsFrom compile
}
}
dependencies {
// Just examples, the real list is longer.
// The point is that h2database is only included on desktop,
// and ormlite is only included on Android.
android 'com.j256.ormlite:ormlite-jdbc:5.0'
desktop 'com.h2database:h2:1.4.192'
}
我觉得这个不错。但是,当我编译desktopUI
或androidUI
时,我可以看到,尽管reusableLibrary
的依赖项以我所希望的方式包含在类路径中,但reusableLibrary
本身提供的实际JAR却未包含在内。这当然会导致构建失败。我怀疑我没有正确设置reusableLibrary
;我不清楚配置{}
块的作用
为什么
reusableLibrary
中的编译项没有包含在UI项目的类路径中?以这种方式包含特定于平台的依赖项的规范方法是什么?原始配置非常接近正确。关键是要从以下方面理解此依赖关系图:
这是Java插件各种依赖项配置的可视化,它是“依赖项列表”的渐变ese。当您将compile
行添加到dependencies{…}
块时,您将dependency
元素添加到compile
依赖项列表中
默认的
依赖项配置是特殊的;除非使用configuration:
参数选择了另一个,否则它是包含在编译项目(“路径”)
行中的。这意味着在构建库时,运行时
依赖项列表(包括库本身编译的jar)将添加到客户机项目的类路径中
原始配置在此图中创建了两个新节点,
desktop
和android
,并使用extendsFrom
将它们耦合到compile
。它们不会以其他方式连接到图形!现在,原始配置的问题很明显:通过将上游项目切换到这两个项目中的任何一个,它将丢失运行时编译的代码。这就解释了类路径省略的原因
解决方案比仅仅将桌面
和安卓
定位在运行时
要微妙得多。为了确保在添加测试时所有内容都正确地解耦,我们需要一个额外的依赖配置层,以防止testCompile
间接依赖运行时。此外,库的源代码本身可能需要类路径上的东西来进行类型检查;我们可以使用compileOnly
进行此操作。最终解决方案如下所示:
configurations {
desktopCompile
androidCompile
compileOnly.extendsFrom desktopCompile
testCompile.extendsFrom desktopCompile // Assuming tests run on the desktop
desktop {
extendsFrom desktopCompile
extendsFrom runtime
}
android {
extendsFrom androidCompile
extendsFrom runtime
}
}
dependencies {
androidCompile "some.android:dependency"
desktopCompile "other.desktop:dependency"
}