Skip to main content

Simple Library with Signature

In this tutorial, we are going to build our minimal component with a digital signature.

The sample project is here.

Project setup#

pom.yaml#

pom.yaml
group: jarbirdsamplesartifactId: simplelibversion: 1.0

The version suffix -SNAPSHOT is removed. Then we may publish the component again.

Before you start, you may want to setup a temporary Gradle environment for this tutorial. Then your working environment will not be messed up.

Run it, the first attempt#

$ ./gradlew jbPublish                                           Build with Groovy build scriptFill in the property values in `gradle.properties` before build.
> Task :signSimplelibPublication FAILEDgpg: skipped "........": No secret keygpg: signing failed: No secret key
FAILURE: Build failed with an exception.
* What went wrong:Execution failed for task ':signSimplelibPublication'.> Process 'command 'gpg2'' finished with non-zero exit value 2

It seems thing does not go well. It is because we have not set up the key used for signing the artefact.

GnuPG#

We need to set up a signing key pair. (If you already have it, just skip this part) It is a one-off task, that we may reuse the key pair for all of our projects. There are various choices to do so, but we do the simplest thing here. Please refer to the Signing configuration for other possibilities.

We need to have an implementation of GnuPG installed on our computer. There are a few choices:

Keypair can be generated by the command gpg --gen-key. You need to provide your name and email address.

$ gpg --gen-keygpg (GnuPG/MacGPG2) 2.2.24; Copyright (C) 2020 Free Software Foundation, Inc.This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law.
Note: Use "gpg --full-generate-key" for a full-featured key generation dialog.
GnuPG needs to construct a user ID to identify your key.
Real name: Jarbird DemoEmail address: jarbird.demo@fake-email.comYou selected this USER-ID:    "Jarbird Demo <jarbird.demo@fake-email.com>"
Change (N)ame, (E)mail, or (O)kay/(Q)uit? O

You will be asked for a passphrase to protect the key pair at this point. It is a passphrase to protect your keybox file. If you already have a keybox, use the same passphrase. Otherwise, create a new passphrase and keep it safe.

We need to generate a lot of random bytes. It is a good idea to performsome other action (type on the keyboard, move the mouse, utilize thedisks) during the prime generation; this gives the random numbergenerator a better chance to gain enough entropy.We need to generate a lot of random bytes. It is a good idea to performsome other action (type on the keyboard, move the mouse, utilize thedisks) during the prime generation; this gives the random numbergenerator a better chance to gain enough entropy.gpg: key BCCF8CD8B61806FE marked as ultimately trustedgpg: revocation certificate stored as '/Users/me/.gnupg/openpgp-revocs.d/6BA0B340ABB2411040589423BCCF8CD8B61806FE.rev'public and secret key created and signed.
pub   rsa3072 2021-05-12 [SC] [expires: 2023-05-12]      6BA0B340ABB2411040589423BCCF8CD8B61806FEuid                      Jarbird Demo <jarbird.demo@fake-email.com>sub   rsa3072 2021-05-12 [E] [expires: 2023-05-12]$

The generated key is identified by the key ID (that ended with B61806FE)

gradle.properties#

The Jarbird plugin uses the key ID and passphrase specified in gradle.properties. It could be in ~/.gradle/gradle.properties or gradle.properties under the project directory. We may also specify these pieces of information in environment variables, which may be more suitable for CI/CD environment.

caution

Putting this information at ~/.gradle/gradle.properties or environment variable is preferable to avoid putting sensitive information in a project. we put the gradle.properties in this project just for simplifying the demonstration.

gradle.properties
# ...signing.gnupg.keyName=B61806FEsigning.gnupg.passphrase=your-GnuPg-passphrase# ...

The keyName is the last 8 characters of the key ID in the result of key generation. If you forget it, use gpg --list-key to find it.

The gradle.properties in the sample project contains these entries for your reference.

Run it, the second attempt#

$ ./gradlew jbPublishBuild with Groovy build scriptFill in the property values in gradle.properties before build.
> Configure project :
> Task :jbDokkaHtmlSimplelibInitializing pluginsDokka is performing: documentation for simplelibValidity checkCreating documentation models
WARN: The registry key 'java.correct.class.type.by.place.resolve.scope' accessed, but not loaded yet
> Task :jbDokkaHtmlSimplelibTransforming documentation model before mergingMerging documentation modelsTransforming documentation model after mergingCreating pagesTransforming pagesRendering

BUILD SUCCESSFUL in 8s9 actionable tasks: 9 executed

We did it successfully. The produced results are in ~/.m2/repository/jarbirdsamples/simplelib/1.0

$ ls -1 ~/.m2/repository/jarbirdsamples/simplelib/1.0simplelib-1.0-javadoc.jarsimplelib-1.0-javadoc.jar.ascsimplelib-1.0-sources.jarsimplelib-1.0-sources.jar.ascsimplelib-1.0.jarsimplelib-1.0.jar.ascsimplelib-1.0.modulesimplelib-1.0.module.ascsimplelib-1.0.pomsimplelib-1.0.pom.asc

The files with the .asc extension are the signature file. Note that the metadata-local.xml file when building 1.0-SNAPSHOT is not here. The non SNAPSHOT version does not need the file.

Bonus: Setup temporary Gradle environment for tutorial #

We may set up an isolated Gradle environment for this tutorial. set the environment variable GRADLE_USER_HOME like this.

export GRADLE_USER_HOME=~/.gradle_jarbird_trial

Then Gradle uses the directory ~/.gradle_jarbird_trial instead of the default ~/.gradle for all working and caching files.

If you are using zsh shell, you may want to enable autoenv plugin so that it is done automatically.

In this sample, we have set up the environment variable in the .in file and undo it in the .out file.

.in
# setup GRADLE_USER_HOME automatically for https://github.com/zpm-zsh/autoenvexport GRADLE_USER_HOME=~/.gradle_jarbird_trial
.out
# setup GRADLE_USER_HOME automatically for https://github.com/zpm-zsh/autoenvunset GRADLE_USER_HOME

It may take a while to use this alternate environment to build the Gradle project for the first time. It will load the Gradle itself, and all plugin and library dependencies for this project.