Some elements are removed when generate a pom.xml using the maven-publish plugin

I tried to generate a pom.xml that is similar to the Maven multi-project. Oddly enough, I noticed that “version” and “description” is not generated. I have created the build.gradle of minimum configuration, please look at this.

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
    }
}
  ext {
    mavenRepository = "repository"
}
  project.group = "com.test"
project.version = "1.0.0"
  apply plugin: 'maven-publish'
    createPom = {
    parent {
        groupId "org.sonatype.oss"
        artifactId "oss-parent"
        version "7"
    }
      name "Test Parent"
    description "This is a test."
    url "https://test.com/"
    inceptionYear "2012"
      modules {
        module "test-library"
    }
}
  publishing {
    publications {
        maven(MavenPublication) {
            artifactId "test-parent"
              pom.withXml {
                asNode().children().last() + createPom
            }
        }
    }
    repositories {
        maven {
            url(mavenRepository)
        }
    }
}

The following error occurs is this.

C:\Verify>gradle publish
Creating properties on demand (a.k.a. dynamic properties) has been deprecated an
d is scheduled to be removed in Gradle 2.0. Please read http://gradle.org/docs/c
urrent/dsl/org.gradle.api.plugins.ExtraPropertiesExtension.html for information
on the replacement for dynamic properties.
Deprecated dynamic property: "createPom" on "root project 'Verify'", value: "bui
ld_6gm9jhjtls60i9un...".
:generatePomFileForMavenPublication
:publishMavenPublicationToMavenRepository FAILED
  FAILURE: Build failed with an exception.
  * What went wrong:
Execution failed for task ':publishMavenPublicationToMavenRepository'.
> Failed to publish publication 'maven' to repository 'maven'
   > Unable to initialize POM pom-default.xml: Missing version element from pare
nt element for project com.test:test-parent
  * Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug
option to get more log output.
  BUILD FAILED
  Total time: 7.004 secs

“build/publications/maven/pom-default.xml” that have been generated.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.test</groupId>
  <artifactId>test-parent</artifactId>
  <version>1.0.0</version>
  <packaging>pom</packaging>
  <parent>
    <groupId>org.sonatype.oss</groupId>
    <artifactId>oss-parent</artifactId>
  </parent>
  <name>Test Parent</name>
  <url>https://test.com/</url>
  <inceptionYear>2012</inceptionYear>
  <modules>
    <module>test-library</module>
  </modules>
</project>

gralde may not be able to interpret them, but it should be output pom.xml as intended. Thanks.

Seems like this has something to do with using XmlMarkupBuilder to define the pom content, where some of the element names are already in scope for the closure. There may be a groovy way to solve this, or you could build the pom using the XML Node API:

apply plugin: 'maven-publish'
def createPom = {
    name "Test Parent"
    url "https://test.com/"
    inceptionYear "2012"
    modules {
        module "test-library"
    }
}
publishing {
    publications {
        maven(MavenPublication) {
            artifactId "test-parent"
            pom.withXml {
                asNode().appendNode("description", "This is a test.")
                def parent = asNode().appendNode("parent")
                parent.appendNode("groupId", "org.sonatype.oss")
                parent.appendNode("artifactId", "oss-parent")
                parent.appendNode("version", "7")
                asNode().children().last() + createPom
            }
        }
    }

Just tested and this also seems to work by telling the XML Closure to resolve DELEGATE_ONLY:

def createPom = {
    parent {
        groupId "org.sonatype.oss"
        artifactId "oss-parent"
        version "7"
    }
    name "Test Parent"
    description "This is a test."
    url "https://test.com/"
    inceptionYear "2012"
    modules {
        module "test-library"
    }
}
createPom.resolveStrategy = Closure.DELEGATE_ONLY

Oops, It was my mistake? I think that when added to documents, it is very helpful. http://www.gradle.org/docs/current/userguide/publishing_maven.html

Hmm, however, I do not understand why it works. Apparently, my knowledge about the closure is will not be enough… Thank you anyway.

It’s confusing, I know…

I’m guessing that the XML builder is using methodMissing to generate the xml from the closure. But since there is already a ‘version’ and ‘description’ in the scope of the closure (on the containing ‘project’ instance), these are not ‘missing’ so the XML elements are not generated. By telling the closure only to resolve against the delegate, and not the owner of the closure, the ‘version’ and ‘description’ are no longer in scope.

Hi Daz DeBoer I see, I was able to understand it in your favor :smiley: Thank you!