Artifact Signing in Multi Project Build


(Tom Hartwell) #1

I have a multiproject build where (simplified for this post) I have a project that produces a JAR and then another Java Application project depending on that JAR. I’d like to sign all the dependencies coming from the JAR project (including the JAR from the project itself) when zipping up the Java Application. Here was my attempt:

project('MyApp') {
 apply plugin: 'application'
 apply plugin: 'signing'
 mainClassName = "com.MyMain"
 dependencies {
  runtime project(':MyJar')
 }
 signing {
  sign configurations.runtime
 }
}

Gradle is still a bit like black magic to me as I learn more of the internals. What I see happening in the build script above is that no signing happens when running:

gradle :MyApp distZip

After some research I saw that “configurations.runtime.files” might be more promising, but then I don’t want to sign the files until after they are copied to somewhere local, but before they get bundled into the zip file.

Has anyone done this before or anyone able to offer guidance?

TIA, Tom


(Tom Hartwell) #2

I was able to craft a solution, without using the signing plugin. To me it doesn’t seem idiomatic of Gradle, if there is a better approach, I’d love feedback

project('MyApp') {
 apply plugin: 'application'
 mainClassName = "com.MyApp"
 dependencies {
  runtime project(':MyJar')
 }
       task explodeZip(dependsOn: 'distZip', type: Copy) {
  from zipTree('build/distributions/MyApp.zip')
  into 'build/unsigned'
 }
    task signJars(dependsOn: 'explodeZip') {
  new File('tmp/signed').mkdirs()
  fileTree('build/unsigned/MyApp/lib').each { File file ->
        ant.signjar(destDir: 'tmp/signed', jar: file, alias:"my-alias", keystore:"my-store", storepass:"mypass", preservelastmodified:"true")
     }
    }
          task signZip(dependsOn: 'signJars', type: Zip) {
     baseName 'MyApp-signed'
     into('lib') {
      from('tmp/signed')
     }
     into('bin') {
      from('build/unsigned/MyApp/bin')
     }
    }
}

Then calling: gradle :MyApp:signZip seems to do the trick


(Peter Niederwieser) #3

The signing plugin signs a configuration’s artifacts, not its dependencies. As such you’ll have to sign the Jar when building it, rather than when consuming it, and you can’t sign third-party code (at least not without dropping down to the task level). See Specifying what to sign in the Gradle User Guide.


(Tom Hartwell) #4

Ok that makes sense, so it looks like if I have a requirement to sign third-party jars, this is a feasible way to do it.

Follow up question for you, Peter:

If I want to make the signed zip that is the output of the signZip task to be the artifact that another project would depend on, how would I modify the above project to make that fit into the way projects work out dependent artifacts?

Specifically, I have a WAR project that will need to bundle this signed zip into its WAR artifact, but I am not sure how that would work.