Skip to content
Latchkey

Java "package X is declared in module Y, which does not export it" - Fix in CI

JPMS strongly encapsulates packages: a module only exposes packages it explicitly exports. Your code uses a type from a package the owning module keeps internal, so it is invisible even though the module is read.

What this error means

javac fails with package com.example.internal is declared in module com.example.lib, which does not export it to module com.example.app. The class exists but the package is not exported to you.

java
error: package com.example.internal is declared in module com.example.lib,
which does not export it to module com.example.app
import com.example.internal.Helper;
                           ^

Common causes

Using an unexported (internal) package

You depend on a package the library deliberately keeps internal; JPMS forbids access from outside.

Reflection into a non-open package

A framework reflects into a package that is exported but not opens, so deep reflective access is denied.

Missing a qualified export

In a multi-module repo you own, the producing module exports the package only to specific modules and not to the consumer.

How to fix it

Export the package (if you own the module)

Add an exports directive to the producing module.

Java
module com.example.lib {
  exports com.example.internal;   // or: exports ... to com.example.app;
}

Open the package for reflection

If a framework needs deep reflection, open rather than export.

Java
module com.example.lib {
  opens com.example.model to com.fasterxml.jackson.databind;
}

Break encapsulation at launch as a last resort

For third-party internals you cannot change, add the flag explicitly (and treat as debt).

Terminal
java --add-exports com.example.lib/com.example.internal=ALL-UNNAMED -jar app.jar

How to prevent it

  • Depend only on exported, public packages of other modules.
  • Use opens ... to for frameworks that need reflective access.
  • Avoid --add-exports/--add-opens for code you can refactor to the public API.

Related guides

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