uploadArchives fails during internal clone step when using Groovy String

If you use a Groovy String as a property value (didn’t try the key as that seems less useful) inside of the pom.project being generated, then it will fail because of a ‘NullPointerException’. Stack trace included after the example.

I came across this while auto-populating a map that I pass into properties when building the POM file to publish. The workaround is to make it a normal String rather than a GString, but it was certainly a surprise (’“4.10.3-snapshot-${luceneSnapshotNumber}”.toString()’).

Simple Gradle project example:

apply plugin: 'maven'
  def luceneSnapshotNumber = '1637985'
  uploadArchives {
  repositories {
    mavenDeployer {
      pom.project {
        // Works
        //properties 'lucene.version' : "4.10.3-snapshot-1637985"
        //properties 'lucene.version' : "4.10.3-snapshot-" + luceneSnapshotNumber
        //properties 'lucene.version' : '4.10.3-snapshot-1637985'
        //properties 'lucene.version' : '4.10.3-snapshot-' + luceneSnapshotNumber
        //Does not work
        properties 'lucene.version' : "4.10.3-snapshot-${luceneSnapshotNumber}"
      }
    }
  }
}

The stack trace points the finger to the culprit:

Caused by: java.lang.NullPointerException
 at org.apache.maven.project.ModelUtils.cloneProperties(ModelUtils.java:1264)
 at org.apache.maven.project.ModelUtils.cloneModelBaseFields(ModelUtils.java:318)
 at org.apache.maven.project.ModelUtils.cloneModel(ModelUtils.java:953)
 at org.apache.maven.project.MavenProject.deepCopy(MavenProject.java:267)
 at org.apache.maven.project.MavenProject.clone(MavenProject.java:1945)
 at org.gradle.api.publication.maven.internal.DefaultMavenPom.getEffectivePom(DefaultMavenPom.java:164)
 at org.gradle.api.publication.maven.internal.DefaultMavenPom.writeTo(DefaultMavenPom.java:189)
 at org.gradle.api.publication.maven.internal.DefaultMavenPom$1.execute(DefaultMavenPom.java:199)
 at org.gradle.api.publication.maven.internal.DefaultMavenPom$1.execute(DefaultMavenPom.java:197)
 at org.gradle.internal.IoActions$TextFileWriterIoAction.execute(IoActions.java:110)

There’s not much we can do here, as this code is directly populating the Maven object model. The new ‘maven-publish’ plugin doesn’t expose Maven APIs, which gives us better control over what’s going on.

Thanks Peter. I was afraid that that might be the answer. I realize it’s on the outs, but we could use Groovy to intercept those calls and act accordingly, but I realize that is not a priority for this likely-to-be rare issue.

The only reasons I’m not using the new ‘maven-publish’ plugin is because:

  • There are far less examples of it - I could not figure out how to sign the POM or as conveniently generate the POM as the above syntax.

Do you happen to know how to sign the POM using the new plugin? And, while I’m begging, how to ensure it publishes to the appropriate repo (snapshot versus not)?

The new publish plugins still have a few limitations. AFAIK, signing is one of them.

Thanks again Peter.

Any idea when those limitations will go away?

I don’t have any information on that.