How to Bundle Internal Dependencies with a Published SDK in Gradle?

39 Views Asked by At

I'm working on a multi-module Gradle project named layers with the following structure and subprojects:

layers/
|- build.gradle.kts
|- settings.gradle.kts
|- buildSrc/
|  - build.gradle.kts
|- layers-sdk/
|  - build.gradle.kts
|- layers-api/
|  - build.gradle.kts
|- libs/
|  - build.gradle.kts

In settings.gradle.kts, the subprojects are included as follows:

include(
    "layers-sdk",
    "layers-api",
    "libs",
)

The layers-sdk module has dependencies on the other projects, specified in its build.gradle.kts like this:

dependencies {
  implementation(project(":libs"))
...
}

My goal is to publish layers-sdk to a Maven repository, including its internal dependencies (libs in this case), without publishing those internal dependencies separately to Maven. However, when I try to publish the SDK it add the internal dependencies on the generated POM:

<dependency>
  <groupId>com.test.ep</groupId>
  <artifactId>lib</artifactId>
  <version>0.0.1</version>
  <scope>runtime</scope>
</dependency>

I attempted to bundle everything into the same jar and remove the references from the generated POM file with the following configuration:

tasks.jar {
  dependsOn(":libs")
  from(
    zipTree(project(":libs").tasks.getByName("jar").outputs.files.singleFile)
  )
  ... 
}
publishing {
  publications {
    create<MavenPublication>("main") {
      from(components["java"])
      version = scmVersion.version
      pom.withXml {
         <CODE TO EXCLUDE THE DEPENDENCIES> 
      }
    }
  }
}

However, this approach resulted in an error when importing the SDK into the application:

   > Could not find com.test.ep:lib:0.0.1.
     Searched in the following locations:
       - file:/Users/me/.m2/repository/com/test/ep/lib/0.0.1/lib-0.0.1.pom
     Required by:
         project : > com.test:layers-sdk:0.21.0

Does anyone know how to correctly bundle internal dependencies with a published SDK in Gradle, so that the SDK can be used without separately publishing its internal dependencies?

1

There are 1 best solutions below

1
Simon Jacobs On

The dependencies that are included in a Java library publication are those in the apiElements and runtimeElements configurations. These are the collections of dependencies used for (i) compiling against and (ii) executing the library respectively (documentation).

You can't add dependencies to these configurations directly. Instead, they obtain dependencies because they extend from the more familiar configurations of api (for apiElements) and implementation and runtimeOnly (for runtimeElements), to which you have added dependencies.

Therefore you can remove the dependencies from the publication (and thus the POM file) by removing these extendsFrom relations:

configurations {
    apiElements { setExtendsFrom(emptySet()) }
    runtimeElements { setExtendsFrom(emptySet()) }
}