Trusted CA Certificates¶
Import custom CA certificates into the bundled JVM's cacerts keystore at build time.
Use Case¶
Corporate proxies, VPN gateways, or ISP-level filtering services often
use a private root CA that is not trusted by the default JDK trust store. Without their
certificate, any HTTPS connection your app makes will throw an SSLHandshakeException.
Instead of asking users to patch their JVM manually, Nucleus lets you declare the certificates once in your build script — they are imported automatically during packaging.
Configuration¶
nativeDistributions {
trustedCertificates.from(files(
"certs/company-proxy-ca.pem",
"certs/company-proxy-ca-2.pem"
))
}
Both PEM (-----BEGIN CERTIFICATE-----) and DER (binary) formats are accepted.
How It Works¶
- After the JLink runtime image is created, Nucleus copies it to a separate
runtime-patched/directory. - For each certificate file, it runs:
createDistributableandcreateSandboxedDistributableboth use the patched runtime, so every packaging format (DMG, NSIS, DEB, PKG, AppX…) embeds the trusted certificate.
Alias Generation¶
Each certificate is imported under a unique alias derived from its filename and a short SHA-256 fingerprint of its content:
This guarantees no collision even when multiple certificate files share the same name
(e.g. two different ca.crt from different directories).
Idempotency¶
If a certificate with the same alias is already present in cacerts, the import is
silently skipped. Rebuilding the project without changing the certificate files or the
JLink runtime is instant (the patchCaCertificates Gradle task is up-to-date).
Gradle Task¶
| Task | Description |
|---|---|
patchCaCertificates |
Copies the runtime image and imports all configured certificates |
The task is only registered when trustedCertificates is non-empty. It runs
automatically as part of createDistributable; you do not need to invoke it manually.
createRuntimeImage
↓
patchCaCertificates ← copies runtime, runs keytool for each cert
↓
createDistributable
createSandboxedDistributable
↓
packageDmg / packageDeb / packageNsis / …
Notes¶
- The original JLink runtime image is never modified. The patched copy lives in
build/compose/tmp/<appName>/runtime-patched/. - The
keytoolbinary used is the one from the JDK configured viajavaHome(or the Gradle daemon's JVM if not set). - This feature patches the bundled JVM only. The host machine's JVM is not affected.