As part of GSoC, I am developing a plugin that helps developers configure POM more easily. My work mainly focuses on reducing duplicated code and adding validation so that developers can use it more conveniently.
My ultimate goal is to enable developers to configure POM using my plugin and then publish their work through tools such as vanniktech/maven-publish.
Understanding Hierarchical Configuration Management
In multi-module Gradle projects, managing POM configurations can become a maintenance nightmare if you publish projects to Maven Central or another Maven repository. The primary challenge arises when each module and artifact require their own POM definition - even a single configuration change requires updating POM information across all modules throughout the project.
To address this issue, in the new https://plugins.gradle.org/plugin/io.github.yonggoose.maven.central.utility.plugin.setting and https://plugins.gradle.org/plugin/io.github.yonggoose.maven.central.utility.plugin.project plugins, I implemented a hierarchical management structure where POM configuration is defined once in the root project and automatically inherited by all submodules. This approach maintains consistency while providing flexibility - submodules can override specific properties when needed, ensuring both structural integrity and adaptability.
Root Project Configuration
Here's how you can set up centralized POM management in your root project:
Root Project's build.gradle.kts
plugins {
id("java")
id("io.github.yonggoose.maven.central.utility.plugin.project") version "0.1.7"
id("maven-publish")
}
rootProjectPom {
groupId = "io.github.yonggoose"
artifactId = "organization-defaults"
version = "1.0.0"
organization {
name = "YongGoose"
url = "https://github.com/YongGoose"
}
mailingLists {
mailingList {
name = "Developers"
subscribe = "dev-subscribe@example.org"
unsubscribe = "dev-unsubscribe@example.org"
post = "dev@example.org"
archive = "https://example.org/archive"
}
}
...
}
With this root project configuration, all POM settings are automatically inherited by submodules.
Verifying Inherited Configuration in Submodules
Sub Project's build.gradle.kts
tasks.register("verifyPom") {
doLast {
if (!project.extensions.extraProperties.has("mergedDefaults")) {
throw GradleException("there is no merged defaults")
}
val pom = project.extensions.extraProperties.get("mergedDefaults") as OrganizationDefaults
check(pom.groupId == "io.github.yonggoose")
check(pom.artifactId == "organization-defaults")
check(pom.version == "1.0.0")
check(pom.organization?.name == "YongGoose")
check(pom.organization?.url == "https://github.com/YongGoose")
check(pom.mailingLists.size == 1)
check(pom.mailingLists.name == "Developers")
check(pom.mailingLists.subscribe == "dev-subscribe@example.org")
check(pom.mailingLists.unsubscribe == "dev-unsubscribe@example.org")
check(pom.mailingLists.post == "dev@example.org")
check(pom.mailingLists.archive == "https://example.org/archive")
}
}
As demonstrated above, submodules can access inherited POM properties through mergedDefaults, confirming that the root project's POM attributes are successfully propagated. Additionally, submodules retain the flexibility to override specific properties when necessary.
Integration with Vanniktech Maven Publish Plugin
The Gradle Maven Publish Plugin (vanniktech) is a popular choice for publishing Android and Kotlin libraries to Maven Central, JCenter, and Nexus repositories. Here's how Maven-Central-utility-plugins-for-Gradle seamlessly integrates with it:
import io.github.yonggoose.organizationdefaults.OrganizationDefaults
plugins {
id("java")
id("io.github.yonggoose.maven.central.utility.plugin.project") version "0.1.7"
id("com.vanniktech.maven.publish") version "0.34.0"
id("maven-publish")
}
rootProjectPom {
groupId = "io.github.yonggoose"
artifactId = "organization-defaults"
version = "1.0.0"
...
}
afterEvaluate {
val mergedPom = project.extensions.extraProperties.get("mergedDefaults") as OrganizationDefaults
mavenPublishing {
coordinates(
groupId = mergedPom.groupId,
artifactId = mergedPom.artifactId,
version = mergedPom.version
)
pom {
name.set(mergedPom.name)
description.set(mergedPom.description)
url.set(mergedPom.url)
...
}
}
}
This integration demonstrates how Maven-Central-utility-plugins-for-Gradle's centralized configuration management works seamlessly with existing publishing workflows, eliminating the need for repetitive POM configuration across multiple modules.
Links
If you're interested, please check out the links below:
- Project: GSoC maven-central-publishing-plugin-for-gradle-with-new-apis
- Repository : https://github.com/YongGoose/Maven-Central-utility-plugins-for-Gradle
- Discussion Channel: maven-central on the Gradle Community Slack
- Demo video : GSoC 2025 - Yongjun - Maven Central Publishing
Credits
This GSoC project was carried out under the guidance of my mentor, Oleg, to whom I am deeply grateful for his support and valuable insights. (Best mentor ever!!)
I would also like to acknowledge other mentors, such as martin, who have provided helpful feedback along the way!!
Top comments (0)