loading...

Sign Eclipse plugin by Gradle

kengotoda profile image Kengo TODA ・2 min read

When we distribute Eclipse plugin, it is better to sign your .jar files by jarsigner bundled with JDK. By this process user can install your plugin without warning like this.
In Eclipse wiki we have Jar Signing page, but it explains no detailed method to sign. Here let's see how Gradle can sign your .jar files.

To sign by jarsigner, you need Java Keystore file that stores keychain. We can use keytool to generate self-signed signature, but here we'll use Let's Encrypt to generate non self-signed signature.

First, follow interaction of Let's Encrypt, then you can generate privkey.pem and fullchain.pem. Second, use openssl command to generate .p12 file that is necessary to generate Java Keystore. Here is example:

$ openssl pkcs12 -export \
  -in fullchain.pem -inkey privkey.pem \
  -out your.p12 \
  -name eclipse-plugin

Third, generate .jks file by keytool command:

$ keytool -importkeystore \
  -srckeystore your.p12 -srcstorepass $SRC_PASS -srcstoretype PKCS12 \
  -destkeystore your.jks -deststorepass $DEST_PASS 

We use this .jks file to sign, so remember your $DEST_PASS. You also need to keep this .jks file secret. If you're using Travis CI, encrypt-file command is your friend.

OK now we have all necessary things, let's config our build.gradle file.
What you need is a function to sign both plugins jar file and feature jar files. Groovy itself doesn't provide feature to sign, so use Ant's SignJar task instead like below:

// sign all .jar file under specified dir
ext.signJar = { File dir ->
  def keystorepass = project.hasProperty('DEST_PASS') ? keystorepass : '';
  if (keystorepass.isEmpty()) {
    print 'to sign eclipse plugins, set "DEST_PASS" project property'
    return
  }

  dir.traverse(type: FILES, nameFilter: ~/.*\.jar$/) {
    def relativePath = rootDir.toPath().relativize( it.toPath() )
    println "signing ${relativePath}"
    ant.signjar(
        destDir: it.parentFile,
        jar: it,
        alias: 'eclipse-plugin',
        keystore: "path/to/your.jks",
        storepass: keystorepass,
        tsaurl: 'http://timestamp.digicert.com',
        verbose: true
    )
  }
}

Well done! You can simply invoke this function between jar task and artifacts.xml file generation (because this artifacts.xml contains md5 hash of .jar files).

Here is a PR that introduces jarsigner to SpotBugs build, you may check it as working solution. It uses Gradle 5.0 RC3, but it should work with Gradle 4 too.

Posted on by:

kengotoda profile

Kengo TODA

@kengotoda

Expert of Java, JavaScript, JVM bytecode, build and CI. Publishes SpotBugs plugin, Java libraries, Jenkins plugin and open-source ebook about Maven3.

Discussion

markdown guide