Solve the problem that the subprojects of the Gradle parent project cannot obtain the properties of the subproject
Summary
Recently, I have been tossing about the unified management of Gradle's dependency versions, which is really a pitfall step by step. At the beginning, we turned to ChatGPT to provide two plug-ins, one is java-platform and the other is io.spring.dependency-management. I chose to use java-platform , but various attempts resulted in errors. If you are interested, you can take a look at the examples on the official website.
https://docs.gradle.org/current/userguide/java_platform_plugin.html
After several searches, I found that there is a new version management method dependencyResolutionManagement
after Gradle7. The official website introduces it as follows.
https://docs.gradle.org/current/userguide/platforms.html
But the introduction on the official website is too fragmented, so I googled it again and found the following post, which introduces it in great detail.
https://zhuanlan.zhihu.com/p/570009095?utm_id=0
main content
parent project settings.gradle
rootProject.name = 'jia'
include 'jia-core', 'jia-mapper-common'
dependencyResolutionManagement {
versionCatalogs {
libs {
library('slf4j.api', 'org.slf4j:slf4j-api:1.7.30')
library('pagehelper', 'com.github.pagehelper:pagehelper:5.1.11')
library('mybatis-plus-core', 'com.baomidou:mybatis-plus:3.3.0')
library('jakarta.inject.api', 'jakarta.inject:jakarta.inject-api:2.0.1')
library('swagger.annotations', 'io.swagger:swagger-annotations:1.5.20')
library('lombok', 'org. projectlombok:lombok:1.18.20')
library('log4j', 'log4j:log4j:1.2.17')
library('slf4j-log4j12', 'org.slf4j:slf4j-log4j12:1.7.5')
}
}
}
parent project build.gradle
allprojects {
group = 'cn.jia'
}
subprojects {
apply plugin: 'java-library'
apply plugin: 'maven-publish'
dependencies {
implementation libs.slf4j.api
annotationProcessor libs.lombok
compileOnly libs.lombok
}
java.sourceCompatibility = JavaVersion.VERSION_17
tasks.withType(JavaCompile).tap {
configureEach {
options.encoding = 'UTF-8'
}
}
test {
useJUnitPlatform()
}
processTestResources. depends On copyTestResources
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
repositories {
maven {
url = version.endsWith('SNAPSHOT') ? rootProject.ext.snapshotsRepoUrl : rootProject.ext.snapshotsRepoUrl
credentials {
username rootProject.ext.repoUsername
password rootProject.ext.repoPassword
}
}
}
}
}
build.gradle of jia-core project
dependencies {
implementation libs.log4j
implementation libs.slf4j.api
implementation libs.slf4j.log4j12
implementation libs.lombok
testImplementation libs.junit.jupiter
testAnnotationProcessor libs.lombok
testImplementation libs.lombok
}
version = '1.1.1-SNAPSHOT'
description = 'jia-core'
build.gradle of jia-mapper-common project
dependencies {
api project(':jia-core')
api libs.pagehelper
api libs.mybatis.plus.core
implementation libs.jakarta.inject.api
api libs.swagger.annotations
}
version = '1.1.1-SNAPSHOT'
description = 'jia-mapper-common'
Problem Discovery
After the configuration is complete, the project can run, and finally unified version management can be performed, without the need to upgrade dependencies for each module individually. The next step is to publish the jia-core module to the maven private server, using Ali's private warehouse, the RELEASE warehouse and the SNAPSHOT warehouse are separate. At this time, the problem arises. My current version is 1.1.1-SNAPSHOT. It should be uploaded to SNAPSHOT, but it is uploaded to RELEASE warehouse.
It must be that the url is wrong, I can only debug it, so I printed the url.
repositories {
maven {
println version
url = version.endsWith('SNAPSHOT') ? rootProject.ext.snapshotsRepoUrl : rootProject.ext.snapshotsRepoUrl
credentials {
username rootProject.ext.repoUsername
password rootProject.ext.repoPassword
}
}
}
It is found that the output is unspecified
, obviously the version has been defined in the build.gradle of the jia-core project, but why it cannot be recognized.
problem solved
Another round of various attempts, Gradle has very few guidance documents, and I really don’t want to go through the official Gradle website.
I have defined version in allprojects , subprojects , ext of the parent project and allprojects , subprojects , ext of the subproject respectively. It is found that the version defined in the parent project can be recognized, but the version defined in the sub-project cannot be recognized.
Then I accidentally saw a post saying that the loading order of Gradle is setting.gradle of the parent project -> build.gradle of the parent project -> build.gradle of the subproject. The subprojects are written on the build.gradle of the parent project, and the build.gradle of the subproject has not been loaded when loading, so naturally the version of the subproject cannot be obtained.
In fact, the official website also has an introduction, but the English is really bad and it is not easy to understand.
https://docs.gradle.org/current/userguide/publishing_maven.html#publishing_maven:deferred_configuration
Now that you know the reason, it’s easy to handle. Just wrap the publishing method with afterEvaluate. The purpose is to load all the configuration files and then load the publishing method, and you can get the version naturally.
allprojects {
group = 'cn.jia'
}
subprojects {
apply plugin: 'java-library'
apply plugin: 'maven-publish'
dependencies {
implementation libs.slf4j.api
annotationProcessor libs.lombok
compileOnly libs.lombok
}
java.sourceCompatibility = JavaVersion.VERSION_17
tasks.withType(JavaCompile).tap {
configureEach {
options.encoding = 'UTF-8'
}
}
test {
useJUnitPlatform()
}
processTestResources. depends On copyTestResources
afterEvaluate {
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
repositories {
maven {
url = version.endsWith('SNAPSHOT') ? rootProject.ext.snapshotsRepoUrl : rootProject.ext.snapshotsRepoUrl
credentials {
username rootProject.ext.repoUsername
password rootProject.ext.repoPassword
}
}
}
}
}
}