Skip to content
Latchkey

Java "jlink"/"jpackage" Failed - Fix Custom Runtime/Installer Builds in CI

jlink (custom runtime image) or jpackage (native installer) failed. Typical causes are a module missing from the module path, jlink refusing an automatic (non-modular) module, or jpackage lacking the platform packaging tool it shells out to.

What this error means

A jlink/jpackage step fails with Error: Module <name> not found, Error: automatic module cannot be used with jlink, or jpackage erroring that an external packaging tool is missing.

build output
Error: Module com.example.app not found, required by com.example.cli
# or, for an automatic module:
Error: automatic module cannot be used with jlink:
  commons.lang3 from .../commons-lang3-3.14.0.jar

Common causes

Module missing from the module path

jlink resolves a closed set of modules. If a required module is not on --module-path, or a requires names a module that is not there, resolution fails.

Automatic module or a missing packaging tool

jlink rejects automatic modules (plain jars on the module path). jpackage shells out to platform tools (e.g. for deb/rpm/msi); if that tool is absent, packaging fails.

How to fix it

Put every required module on the path

Ensure all modules jlink needs are on --module-path, and avoid automatic modules in the image.

Terminal
jlink \
  --module-path "$JAVA_HOME/jmods:target/modules" \
  --add-modules com.example.app \
  --output target/runtime

Install the jpackage platform tool

Provision the OS packaging tool jpackage invokes (and a full JDK that ships jpackage).

.github/workflows/ci.yml
- uses: actions/setup-java@v4
  with:
    distribution: temurin
    java-version: '21'   # full JDK ships jlink + jpackage
# on Linux, install the packaging tool jpackage shells out to (e.g. fakeroot/dpkg or rpm)

How to prevent it

  • Keep all required modules on the module path; avoid automatic modules in jlink images.
  • Use a full JDK that ships jlink and jpackage, and install platform packaging tools.
  • Verify the image resolves (jlink --suggest-providers / a dry assemble) before packaging.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →