Skip to main content

Solve the problem that the subprojects of the Gradle parent project cannot obtain the properties of the subproject

Mr.ChenAbout 2 minarticleJavaGradle

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.htmlopen in new window

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.htmlopen in new window

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=0open in new window

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_configurationopen in new window

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
                     }
                 }
             }
         }
     }
}