This is an automated email from the ASF dual-hosted git repository. achennaka pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/kudu.git
The following commit(s) were added to refs/heads/master by this push: new 35fce9ba2 [Java] KUDU-3677: Fix optional dependencies 35fce9ba2 is described below commit 35fce9ba24b2e376c65fd7a2c50a65ec0a33e02f Author: Abhishek Chennaka <achenn...@cloudera.com> AuthorDate: Tue Jul 15 22:03:42 2025 -0700 [Java] KUDU-3677: Fix optional dependencies This update removes compileUnshaded dependencies from the generated POM and re-adds them with compile scope, including any defined exclusions without the optional configuration attribute. We now use project.configurations.findByName("compileUnshaded") instead of direct access to avoid Could not get unknown property 'compileUnshaded' errors when the configuration is not defined. Change-Id: I5b7593f595b64082d86fb64cbe8f38ff9b2ccb88 Reviewed-on: http://gerrit.cloudera.org:8080/23205 Reviewed-by: Zoltan Chovan <zcho...@cloudera.com> Tested-by: Abhishek Chennaka <achenn...@cloudera.com> Reviewed-by: Alexey Serbin <ale...@apache.org> --- java/gradle/publishing.gradle | 64 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/java/gradle/publishing.gradle b/java/gradle/publishing.gradle index 027c7ac8c..a4ab32e59 100644 --- a/java/gradle/publishing.gradle +++ b/java/gradle/publishing.gradle @@ -79,17 +79,43 @@ publishing { } // Remove the shaded dependencies from the generated pom. + pom.withXml { - def implementationDeps = [] + def implementationDeps = [] def shadedDeps = [] - if (project.configurations.hasProperty("implementation")) { - implementationDeps = project.configurations.implementation.allDependencies + def unshadedDeps = [] + + def implConfig = project.configurations.findByName("implementation") + def shadowConfig = project.configurations.findByName("shadow") + def unshadedConfig = project.configurations.findByName("compileUnshaded") + + if (implConfig) { + implementationDeps = implConfig.allDependencies } - if (project.configurations.hasProperty("shadow")) { - shadedDeps = project.configurations.shadow.allDependencies + if (shadowConfig) { + shadedDeps = shadowConfig.allDependencies } - - def finalDeps = implementationDeps - shadedDeps + if (unshadedConfig) { + unshadedDeps = unshadedConfig.allDependencies + } + // Explanation for the below logic of excluding and including unshadedDeps: + // Given the following sets: + // implDeps = {A, B, C, D} + // shadowDeps = {D, E, F} + // unshadedDeps = {C, D, G} + // + // The logic here computes: + // filteredImplDeps = implDeps - shadowDeps - unshadedDeps = {A, B} + // finalDeps = filteredImplDeps + unshadedDeps = {A, B, C, D, G} + // + // This approach avoids inadvertently excluding dependencies like 'C' and 'G' + // that may appear in unshadedDeps but are not in implDeps. + // While in our current setup `unshadedDeps ⊆ shadowDeps` due to: + // configurations.shadow.extendsFrom(configurations.compileUnshaded) + // this logic ensures correctness in future scenarios where that might not hold. + // It also improves clarity and maintainability for future readers. + def filteredImplDeps = implementationDeps - shadedDeps - unshadedDeps + def finalDeps = filteredImplDeps + unshadedDeps asNode().dependencies.dependency.findAll{ finalDeps.findAll{ dep -> dep.name == it.artifactId*.value()[0][0] @@ -98,6 +124,30 @@ publishing { logger.info "Removing: ${it.artifactId*.value()[0][0]} from pom" assert it.parent().remove(it) } + // Ensure <dependencies> node exists + def dependenciesNode = asNode().dependencies?.getAt(0) + if (!dependenciesNode) { + dependenciesNode = asNode().appendNode("dependencies") + } + + // Add back unshaded dependencies manually with <scope>compile</scope> (to get proper exclusions) + unshadedDeps.findAll { it.group && it.name && it.version }.each { dep -> + logger.info "Adding compileUnshaded: ${dep.group}:${dep.name}:${dep.version}" + def depNode = dependenciesNode.appendNode("dependency") + depNode.appendNode("groupId", dep.group) + depNode.appendNode("artifactId", dep.name) + depNode.appendNode("version", dep.version) + depNode.appendNode("scope", "compile") + + if (!dep.excludeRules.isEmpty()) { + def exclusionsNode = depNode.appendNode("exclusions") + dep.excludeRules.each { ex -> + def exclusion = exclusionsNode.appendNode("exclusion") + exclusion.appendNode("groupId", ex.group ?: "*") + exclusion.appendNode("artifactId", ex.module ?: "*") + } + } + } } } }