-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathbuild.gradle
More file actions
309 lines (268 loc) · 16.2 KB
/
build.gradle
File metadata and controls
309 lines (268 loc) · 16.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
// build.gradle (根项目)
// gradle 官方不推荐这个脚本,但是把这个脚本拆解到子项目里比较麻烦:Some builds may contain a build.gradle(.kts) file in the root project but this is NOT recommended.
// Generally, a build script details build configuration, tasks, and plugins.
// 理论上不加入这个文件也是一个完整的项目,只要每个 module 拥有自己的 build.gradle 就行了。这个 build script 是为了 root project 或者 root module 准备的
// Spring boot 的最新官方文档:https://docs.spring.io/spring-boot/docs/current/reference/html/
// https://huangxshuo.github.io/2021/03/04/apply%20plugin%E5%92%8Cplugins%E4%B8%A4%E7%A7%8D%E5%BA%94%E7%94%A8gradle%E6%8F%92%E4%BB%B6%E7%9A%84%E5%8C%BA%E5%88%AB/
// 没有放进 subprojects 里的内容不会对所有子 module 生效,配也白配
// 这是使用插件的新语法,不同于 apply plugin:如果是在官方仓库里能找到的插件,则 resolve 和 apply 可以用这种写法统一声明,这也实现了自动的 apply true
// The plugins{} block must also be a top-level statement in the build script. It cannot be nested inside another construct (e.g., an if-statement or for-loop).
plugins {
// These plugins are not automatically applied.
// They can be applied in subprojects as needed (in their respective build files).
// // 中文使用指南:https://www.jianshu.com/p/01588c396a29
id 'org.springframework.boot' version '2.7.18' // 在任意子项目里 id 这个插件不再需要版本
// // 这两个版本是如何搭配的,是 initializr 决定的吗?
id("io.spring.dependency-management") version "1.1.7"
// // 大于等于 java/java-library,支持一个 CLI application,能够 bootRun
// id 'application'
// id 'idea'
// // 这些配置会让我们的项目可以从根部进行 gradle clean build,然后也能生成 report
//
// // test 其实是一个 conventional test suit,它也是可配置的 https://docs.gradle.org/current/userguide/jvm_test_suite_plugin.html#sec:declare_an_additional_test_suite
// id 'jvm-test-suite'
// id 'test-report-aggregation'
// Script plugins are Groovy DSL or Kotlin DSL scripts that are applied directly to a Gradle build script using the apply from: syntax. They are applied inline within a build script to add functionality or customize the build process. They are not recommended but it’s important to understand how to work:
// apply from: ' https://sonatype.com/nexus3/repository/raw/gradle/nexus3_v7.gradle '
}
group = 'com.magicliang'
version = '0.0.1-SNAPSHOT'
// 早期处理 lombok 需要这个配置才能让 gradlew build 通过,现在注释这段配置也可以
//configurations {
// compileOnly {
// // 这个插件是依赖于 java-library 插件的,如果在本大scope里没有应用这个插件,则这整个 block 不能工作
// extendsFrom annotationProcessor
// }
// // 全局项目也可以排除掉 logging 依赖,不过还是要让 subModule 排除掉更有效
//}
//dependencyManagement {
// imports {
// mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
// }
//}
// 这个项目不适合放在 allprojects 和 subprojects
apply from: 'script-plugin.gradle' // 请确保此路径正确
dependencies {
// 非官方版本的 starter 列表:https://www.javatpoint.com/spring-boot-starters
// 这些依赖列在这里,不会影响 subProjects,其一般用处是,列出潜在的 starter 依赖列表
// implementation 'org.springframework.boot:spring-boot-starter-actuator'
// implementation 'org.springframework.boot:spring-boot-starter-webflux'
// implementation 'org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j'
// implementation 'org.springframework.cloud:spring-cloud-starter-sleuth'
// implementation 'org.springframework.boot:spring-boot-devtools'
//
// annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
// testImplementation 'org.springframework.boot:spring-boot-starter-test'
// testImplementation 'io.projectreactor:reactor-test'
// testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
// testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
}
// https://docs.gradle.org/current/userguide/toolchains.html#toolchains
java {
// 引入 java 工具链
toolchain {
// 替代了 sourceCompatibility、targetCompatibility
languageVersion = JavaLanguageVersion.of(8)
}
withJavadocJar()
withSourcesJar()
}
allprojects {
// apply plugin: JavaPlugin // 使用类名来使用 java 插件
// java 类库插件,带有 compileJava、compileTestJava、test、jar、javadoc 几个任务。
apply plugin: 'java-library'
apply plugin: 'idea'
// 这些特定版本的插件要在顶层使用 id 声明版本
apply plugin: 'io.spring.dependency-management'
ext {
// spring cloud 和 spring boot 的版本兼容性见: https://start.spring.io/actuator/info
set('springCloudVersion', "2021.0.8")
// --- 统一 JUnit 版本 ---
// 为了解决 NoClassDefFoundError: org.junit.jupiter.api.Named 错误,
// 我们将 JUnit Jupiter 和 Platform 版本统一设置为兼容且较新的版本 (5.9.3 / 1.9.3)
set('junitJupiterVersion', '5.9.3')
set('junitPlatformVersion', '1.9.3') // Platform 版本通常与 Jupiter 的次要版本匹配
// --- 结束 JUnit 版本配置 ---
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
// 可以在这里通过 dependencyManagement 统一管理 JUnit 版本,或者像下面一样显式声明
// dependencies {
// dependency "org.junit.jupiter:junit-jupiter-api:${junitJupiterVersion}"
// dependency "org.junit.jupiter:junit-jupiter-engine:${junitJupiterVersion}"
// dependency "org.junit.platform:junit-platform-commons:${junitPlatformVersion}"
// dependency "org.junit.platform:junit-platform-engine:${junitPlatformVersion}"
// dependency "org.junit.jupiter:junit-jupiter-params:${junitJupiterVersion}"
// }
}
repositories {
// 参考:https://bbs.huaweicloud.com/blogs/257878
// 注意:确保 URL 正确且可访问。部分阿里云链接可能需要调整或验证。
maven { url "https://maven.aliyun.com/repository/public" }
maven { url "https://maven.aliyun.com/repository/central" }
maven { url "https://maven.aliyun.com/repository/jcenter" }
maven { url "https://maven.aliyun.com/repository/google" }
maven { url "https://maven.aliyun.com/repository/gradle-plugin" }
maven { url "https://mirrors.163.com/maven/repository/maven-central" }
maven { url "https://maven.aliyun.com/nexus/content/groups/public/" }
// maven { url "http://maven.oschina.net/content/groups/public/" }
maven { url "https://maven.douban.com" }
maven { url "https://mirrors.cloud.tencent.com/repository/maven-public" }
maven { url "https://repo.huaweicloud.com/repository/maven" }
mavenLocal()
mavenCentral()
}
idea {
module {
downloadJavadoc = true
downloadSources = true
}
}
dependencies {
// --- 为所有项目(包括根项目)配置统一的 JUnit 5 依赖 ---
// 确保在根项目和所有子项目中使用一致的 JUnit 版本,覆盖潜在的冲突
testImplementation "org.junit.jupiter:junit-jupiter-api:${junitJupiterVersion}"
testImplementation "org.junit.jupiter:junit-jupiter-params:${junitJupiterVersion}" // 用于参数化测试
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junitJupiterVersion}"
// 显式管理 JUnit Platform 版本以确保与 Jupiter 版本匹配
testImplementation "org.junit.platform:junit-platform-commons:${junitPlatformVersion}"
testRuntimeOnly "org.junit.platform:junit-platform-engine:${junitPlatformVersion}"
// --- 结束 JUnit 5 配置 ---
}
tasks.withType(JavaCompile).configureEach {
options.fork = true
// 示例:添加编译器警告 (如果需要)
// options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
}
}
// 指定插件作用于子项目
subprojects {
// 插件 apply plugin,version 语法不一样,在 subprojects 里只能用旧语法
// 如果在上下文的一处已经做过 artifact version resolve 的动作,则在另一处(在本例中是 subproject 里)可以使用这种老式的方式来 apply plugin
// apply plugin: 'java'
// 只要子项目激活这两个 plugin 就可以启动,但如果子模块没有这两个配置,则不能使用 bootJar 之类的配置
apply plugin: 'org.springframework.boot'
apply plugin: 'application'
// apply plugin: 'jvm-test-suite' // 用于高级测试套件配置 (可选)
// apply plugin: 'test-report-aggregation' // 用于聚合来自子项目的测试报告 (可选)
configurations {
// all*.exclude group:'org.apache.logging.log4j', module: 'log4j-slf4j-impl'
// 对排除 logback 而言,这个配置最有用,子项目必须排除掉这个依赖
all*.exclude module: 'spring-boot-starter-logging'
// all*.exclude group:'org.springframework.boot', module: 'spring-boot-starter-logging'
// 示例:排除其他潜在冲突的传递依赖 (如果需要)
// all*.exclude group: 'org.unwanted.group', module: 'unwanted-module'
}
repositories {
mavenCentral()
// 要在本地编译自己的 jar 包,需要引入这个依赖
mavenLocal()
}
// 标准地为子项目引入依赖的方式
dependencies {
// 不是本项目的 project,不能用 implementation project 坐标,只能用 implementation 坐标
// 一般的依赖则使用 scope 别名来引用
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testCompileOnly 'org.projectlombok:lombok:1.18.24' // 为测试固定版本
testAnnotationProcessor 'org.projectlombok:lombok:1.18.24'
// 让所有的子模块都拥有基本的 spring 依赖
implementation 'org.springframework.boot:spring-boot-starter'
// 这个依赖让底层能够拥有 log4j2,但并不去掉 logback 的影响
implementation 'org.springframework.boot:spring-boot-starter-log4j2'
// api("com.google.code.gson:gson:2.10!!")
// implementation 才是最需要使用的configuration,因为大多数情况下我们除了专门的 sdk module,不需要 publish api。
// 非 entrance/worker 模块要传递 lib 依赖(如 jackson)给 entrance/worker 模块用,就使用 api,但外围模块应该尽量使用 implementation
implementation("com.google.code.gson:gson") {
// @deprecated
// force = true
version {
strictly("2.10")
}
}
// OpenTelemetry instrumentation BOM 用于统一版本
implementation(platform("io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom:2.10.0"))
implementation 'io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations:2.10.0'
implementation group: 'io.opentelemetry.instrumentation', name: 'opentelemetry-logback-mdc-1.0', version: '2.10.0-alpha'
// 在这里实现了对 spring-boot-test jar 的引入,确切地讲,@SpringBootTest 这个注解依赖于本依赖
// --- 排除 spring-boot-starter-test 的 JUnit 依赖 ---
// 排除 starter-test 传递引入的旧 JUnit 依赖,以确保我们显式声明的版本 (5.9.3/1.9.3) 被使用。
testImplementation('org.springframework.boot:spring-boot-starter-test') {
// 排除 starter-test 中的 JUnit Jupiter 和 Platform 依赖
exclude group: 'org.junit.jupiter', module: 'junit-jupiter'
exclude group: 'org.junit.platform', module: 'junit-platform-commons'
exclude group: 'org.junit.platform', module: 'junit-platform-engine'
// exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' // 如果不需要 Vintage
}
// --- 为子项目重新声明统一的 JUnit 5 依赖 ---
// 这加强了在 allprojects 中设置的版本,并确保它们覆盖 starter-test 的版本。
testImplementation "org.junit.jupiter:junit-jupiter-api:${junitJupiterVersion}"
testImplementation "org.junit.jupiter:junit-jupiter-params:${junitJupiterVersion}"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junitJupiterVersion}"
testImplementation "org.junit.platform:junit-platform-commons:${junitPlatformVersion}"
testRuntimeOnly "org.junit.platform:junit-platform-engine:${junitPlatformVersion}"
// --- 结束子项目的 JUnit 5 配置 ---
}
/*
* 对于测试来讲,子项目的配置是更重要的,这个配置写在外面不生效
* 关于复合 sourceSet,可以参考:
* https://groups.google.com/g/adt-dev/c/EXdoKIMX0wg
* https://docs.gradle.org/current/userguide/building_java_projects.html#sec:custom_java_source_set_paths
* 分离单元测试和集成测试需要仔细阅读这几个帖子:
* https://discuss.gradle.org/t/separate-execution-for-java-unit-and-integration-tests/8713
* https://inspeerity.com/blog/separate-gradle-tasks-for-unit-and-integration-tests
* https://docs.gradle.org/current/userguide/java_testing.html#sec:configuring_java_integration_tests
* https://docs.gradle.org/current/userguide/jvm_test_suite_plugin.html#jvm_test_suite_plugin
* 搜索关键词为:separate unit test and integration test
*/
test {
// 允许测试任务按照计算密集型(cpu-bound)的思路 fork process 执行
maxParallelForks = Runtime.runtime.availableProcessors()
/*
* 这个配置很关键,会让 platform 找到 jupiter 包相关的测试,大致上是激活了 TestEngine 相关的功能,让我们不需要使用 @RunWith(JUnitPlatform.class) 相关的注解。
* 当然,大部分的 IDE 或者 build tools 会自动识别和激活一个缺省的 runner,我们总能得到一个不知道是什么的 runner
*/
useJUnitPlatform {
// 这里面任意一个不打开,即可以让 jupiter 相关的 api 自动搜索到相关测试
// includeEngines 'junit-vintage'
// includeEngines 'junit-jupiter'
// excludeEngines 'junit-jupiter'
testLogging {
events("passed", "skipped", "failed")
// exceptionFormat "full" // 显示失败的完整堆栈跟踪 (可选)
}
}
}
// Configure Java compilation for subprojects (if different from allprojects)
tasks.withType(JavaCompile) {
// 示例:为子项目添加特定的编译器参数
// options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
}
// 示例:如果应用了聚合报告插件,则集成
// tasks.named('check') {
// dependsOn tasks.named('testAggregateTestReport', TestReport)
// }
}
bootJar {
// 每个可以被部署和发布的子模块成为一个 bootJar
enabled = false
}
// 这个配置在当代的 gradle 里暂时占不到用处了,$buildDir 专指每个 module 的 build
//task testReport(type: TestReport) {
// destinationDir = file("$buildDir/reports/allTests")
//// Include the results from the `test` task in all subprojects
//}
//// Configuring the wrapper, the old way (gradle < 4.8 )
//// see https://docs.gradle.org/4.4/userguide/gradle_wrapper.html#sec:wrapper_generation
//task wrapper(type: Wrapper) {
// gradleVersion = '4.4'
// distributionType = Wrapper.DistributionType.BIN
//}
// Configuring the wrapper, the new way (since Gradle 4.8)
// see https://docs.gradle.org/current/userguide/gradle_wrapper.html#customizing_wrapper
wrapper {
gradleVersion = '8.6'
distributionType = Wrapper.DistributionType.BIN
}