use*_*021 8 gradle build.gradle
我最近为 Spring Boot 项目将 Gradle 从 4.x 升级到 6.6。我以为我终于把它全部启动并运行了,但后来意识到我们的一个应用程序可能启动两个不同配置的类型任务BootRun(例如 A 和 B),却无法启动第二个 B 实例。
这是我尝试运行第二个实例时出现的错误:
Build file 'C:\Users\...\build.gradle' line: 17
Execution failed for task ':apps:myapp:bootRunB'.
> The value for task ':apps:myapp:bootRunB' property 'mainClass' is final and cannot be changed any further.
Run Code Online (Sandbox Code Playgroud)
build.gradle这是我的文件中配置任务的部分:
task bootRunB(type: org.springframework.boot.gradle.tasks.run.BootRun, dependsOn: 'build') {
group = 'Application'
doFirst() {
main = bootJar.mainClassName
classpath = bootRun.classpath
systemProperty '...'
}
}
Run Code Online (Sandbox Code Playgroud)
任何建议,将不胜感激。
Gradle 最近引入了一个用于延迟配置的API ,现在插件扩展和任务类型等内部功能已迁移到这个新 API。总之,可以说构建脚本中的(几乎)每个配置属性都应该使用Property<T>or Provider<T>(只读)来实现,而不仅仅是简单类型的 getter 和 setter T。为了提供向后兼容性,许多属性没有更改,但添加了新属性,并且旧属性读取和写入这些新属性。
您的问题也是如此,因为BootRunSpring Boot Gradle 插件中的任务类型扩展了JavaExecGradle 提供的任务类型。添加了新属性mainClass(a Property<string>),并修改了旧属性main以使用新属性。该方法从usinggetMain()读取,并且在使用 Groovy 中的语法时调用的方法写入using 。mainClassProperty.get()setMain(String)main = '...'mainClassProperty.set(String)
这一切都可以正常工作,但 Gradle 为其惰性配置 API 引入了一些附加功能。这些功能之一是可写属性的最终确定 ( Property<>)。在构建过程中的某个时刻,mainClass将出于其原始目的(运行任务)读取任务属性(例如 ),因此该点之后的任何更改都不会生效。在 Gradle 的早期版本中,这会导致很多难以调试的问题,因为 Gradle 不会显示任何错误。现在,一旦出于最初目的而读取这些属性,这些属性就会被最终确定,从而导致当有人随后尝试更改它们时 Gradle 会失败。
关于您的用例,属性mainClass(由 访问main)已经在doFirst闭包中最终确定,因此您需要提前应用此配置。由于您想要将该值设置为属性的值bootJar.mainClassName(这是一个简单的String),因此您必须确保该属性在读取用于配置任务之前具有其最终值bootRunB:
bootJar {
mainClassName = '...'
}
task bootRunB(type: org.springframework.boot.gradle.tasks.run.BootRun, dependsOn: 'build') {
group = 'Application'
main = bootJar.mainClassName
// From this point, bootRun.classpath must not be changed !
classpath = bootRun.classpath
systemProperty '...'
}
Run Code Online (Sandbox Code Playgroud)
为了消除对配置顺序的依赖,您可以创建一个Provider<String>using Project.provider(...):
task bootRunB(type: org.springframework.boot.gradle.tasks.run.BootRun, dependsOn: 'build') {
group = 'Application'
main = provider({ bootJar.mainClassName })
classpath = bootRun.classpath
systemProperty '...'
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9266 次 |
| 最近记录: |