Virtual platforms, publishing, and transitive resolution problems

Using Gradle 5.2.1. I have declared a virtual platform ( in a build plugin to enforce dependency version alignment for a transitive dependency (jackson) via a declaration like this:

implementation enforcedPlatform('com.fasterxml.jackson:jackson-platform:2.9.8')

I use this build plugin in a java-library project which transitively depends on jackson. This works fine. I have a consumer of this library that includes it via a SNAPSHOT dependency in an internal repo. The virtual platform appears to be part of the published POM of the library, specifically in a dependencyManagement block:


The build for the consumer fails:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':copyMessageScript'.
> Could not resolve all files for configuration ':runtimeClasspath'.
   > Could not resolve com.myorg.lib-mylib:lib-foo:1.5-SNAPSHOT.
     Required by:
         project :
      > Could not resolve com.myorg.lib-mylib:lib-foo:1.5-SNAPSHOT.
         > Could not parse POM /home/raman/.m2/repository/com/myorg/lib-mylib/lib-foo/1.5-SNAPSHOT/lib-foo-1.5-SNAPSHOT.pom
            > Could not find com.fasterxml.jackson:jackson-platform:2.9.8.
              Searched in the following locations:
                - file:/home/raman/.m2/repository/com/fasterxml/jackson/jackson-platform/2.9.8/jackson-platform-2.9.8.pom
                - file:/home/raman/.m2/repository/com/fasterxml/jackson/jackson-platform/2.9.8/jackson-platform-2.9.8.jar
      > Could not resolve com.myorg.lib-mylib:lib-foo:1.5-SNAPSHOT.
         > Could not parse POM
            > Could not find com.fasterxml.jackson:jackson-platform:2.9.8.

A workaround appears to be to include the library build as a composite build via includeBuild. However, this is not ideal as these particular projects are not in a mono-repo, and thus not always colocated. Plus, the fact that this works seems to be another bug – should be behavior of the build be this different simply by using a composite build?

Another workaround is given in, which is to explicitly remove the platform declaration from the published artifacts:

publishing {
    publications {
        maven(MavenPublication) {
            pom.withXml {
                asNode().dependencyManagement.dependencies.dependency.findAll { node ->
                    node.groupId[0].text().equals('org.test') &&
                    node.artifactId[0].text().equals('platform') &&
                }.each { node -> node.replaceNode {} }

Some other comments:

The consuming application does also import the same build plugin as the library, and therefore should have a local declaration for the virtual platform, which one might think would resolve the issue.

I see some possibly related issues but nothing exactly like this situation, though one of the workarounds above is from a comment in the first issue here:

The pom.withXml workaround is really messy to do in a Kotlin build plugin also, as its using Groovy XML and duck-typing… found this related issue but argh, I feel like I’m going down a time-wasting rabbit hole here:

UPDATE: Here is the equivalent Kotlin code, which requires the kotlinx.dom dependency:

pom.withXml {
    ?.filter { dep ->
        dep.firstChildElement("groupId")?.textContent == "com.fasterxml.jackson" &&
        dep.firstChildElement("artifactId")?.textContent == "jackson-platform" &&
        dep.firstChildElement("scope")?.textContent == "import"
    ?.forEach { node -> node.removeFromParent() }