我正在为遗留系统设置多模块Gradle构建(替换当前的Ant构建)。但是,我是Gradle的新手,我不知道最好的方法是什么。我想做得对,因为这个构建脚本将会存在很长时间。我已经找到了一种方法可以做一些有效的方法,但是当我在谷歌周围阅读并阅读StackOverflow的答案时,我看到人们使用不同的方式,在我的情况下 - 它不起作用。但也许我做错了什么。我也一直在阅读Gradle in Action一书,但在那里找不到这个特殊的问题。
我的项目根目录中有一个build.gradle文件,其中包含一堆子目录,每个子目录都包含一个子项目。其中大多数是常规Java项目,但也有一些战争和耳朵,这需要一些特殊的包装爱。每个子项目都有自己的build.gradle文件,此时只包含依赖项列表,仅此而已。
我的项目根目录中的build.gradle文件看起来像这样(为了简洁,我省略了War的内容):
configure(javaProjects()) {
jar.doFirst {
manifest {
...
}
}
}
configure(earProjects()) {
apply plugin: 'ear'
ear.doFirst {
manifest {
...
}
}
}
Set<String> javaProjects() {
subprojects - earProjects()
}
Set<String> earProjects() {
subprojects.findAll { it.name.endsWith(".ear") }
}
我以这种方式做事的唯一原因是因为这是我尝试的第一个解决方案,我可以在我的情况下工作。然而,现在脚本正在增长,它开始感觉有点笨重。此外,doFirst
似乎有点尴尬。
但是当我查看StackOverflow时,我看到了使用这样的结构的建议:
allprojects {
tasks.withType(Jar) {
manifest {
...
}
}
tasks.withType(Ear) {
manifest {
...
}
}
}
这似乎更好,但我似乎无法以这种方式重写我的脚本。我得到像这样的错误:
Cannot change configuration ':some.subproject:compile' after it has been resolved.
我不知道如何处理此错误,而且出于某种原因,我似乎无法谷歌。
所以,我的问题是:我确实做错了吗?或者更确切地说:以一种不是惯用的Gradle方式?为了可维护性,我想尽可能地做事。如果是这样的话:我该如何处理错误消息?
答案 0 :(得分:4)
一般情况下,您应该执行第二个代码段中描述的内容:
allprojects {
tasks.withType(Jar) {
manifest {
...
}
}
}
但是这还有一些限制,这还不够。您获得的错误消息意味着您修改了编译配置 AFTER 配置已经解决。例如,当您执行类似
的操作时,就会发生这种情况configurations.compile.files.each...
在配置阶段(例如,在您的清单块中,如上所示)和另一个地方(例如,在您的子项目build.gradle文件中):
dependencies{
compile "org.acme:somelib:1.2.3"
}
另一个问题是,每次调用构建脚本时都会解决编译依赖关系,即使没有触发jar任务也是如此。
建议的解决方法是替换
tasks.withType(Jar) {
manifest {
...
}
}
带
tasks.withType(Jar) {
doFirst{
manifest {
...
}
}
}
这意味着解析配置会推迟到gradle的执行阶段,并且只在需要时才会触发。
在多项目构建中配置项目时,您可以将每个代码段视为整个配置的一部分。你没有“两次”配置项目,但你在不同的地方配置项目的不同方面。
这是当前gradle配置模型的已知限制。
您仍然可以使用
configure(earProjects()) {
}
这里没关系。 IMO只是个人偏好的问题。 gradle项目本身使用'configure'。
我个人更喜欢在项目build.gradle文件中应用 Ear 或 war 等插件,将项目标记为ear / war项目。
要在所有ear项目中共享通用配置,您可以在root build.gradle文件中使用以下内容:
allprojects{
plugins.withType(EarPlugin){
// only applied if it is a ear project
// put ear specific logic here
}
}