Skip to content

AOT compiled modules: drop-in /modules classpath directory in the runtime image (PropertiesLauncher loader.path) — follow-up to #6400 #6592

Description

@delchev

Context

#6400 added classpath loading of AOT-compiled modules: CompiledModuleClassProvider scans classpath*:META-INF/dirigible/*/.compiled on ApplicationReadyEvent and registers the listed, already-compiled classes through JavaLoader.installCompiledModules(...) — no runtime javac. The existing ClasspathExpander lays the jar's META-INF/dirigible/<project>/ payload into registry/public/<project>/ on start, so a single module jar delivers both the compiled classes and the declarative registry content.

What is still missing is a supported way to get such a module jar onto the application classpath of the shipped container image. The image entrypoint is:

ENTRYPOINT ["java", "--add-opens", ..., "-jar", "/dirigible.jar"]

(build/application/Dockerfile) — i.e. Spring Boot's JarLauncher, which offers no mechanism to add external jars. Verifying #6400 end-to-end required hand-exploding the fat jar and copying the module jar into BOOT-INF/lib, which mutates the shipped artifact and defeats the immutability/provenance goal of AOT packaging.

Proposal

Support a conventional drop-in modules directory in the runtime image via Spring Boot's PropertiesLauncher:

ENTRYPOINT ["java", "--add-opens", "java.base/java.lang=ALL-UNNAMED", \
            "--add-opens", "java.base/java.lang.reflect=ALL-UNNAMED", \
            "--add-opens", "java.base/java.nio=ALL-UNNAMED", \
            "-cp", "/dirigible.jar", "-Dloader.path=/modules", \
            "org.springframework.boot.loader.launch.PropertiesLauncher"]

A downstream image (or a volume mount) then simply COPYs AOT module jars into /modules — no rebuild, no exploding, the platform jar is consumed verbatim.

Requirements:

  1. Empty or missing /modules is a strict no-op — boot behavior, classpath, and startup time must be identical to today's java -jar launch. Create the empty directory in the Dockerfile so the launcher never warns about a missing path.
  2. Classpath order must be verified: PropertiesLauncher prepends loader.path entries to the fat jar's own BOOT-INF/classes + BOOT-INF/lib. Confirm that (a) an empty /modules changes nothing and (b) a module jar cannot accidentally shadow platform classes (module packages are gen.* / custom.*, so collisions are not expected — but state that explicitly after verifying).
  3. PropertiesLauncher also honors the LOADER_PATH env var natively — document that as the override for non-default locations; no new Dirigible configuration property is needed.
  4. Keep the existing --add-opens flags — they are required by the runtime regardless of launcher.

Alternative considered and rejected: exploding the fat jar in the image and adding module jars to BOOT-INF/lib — it works (that is how #6400 was verified) but rewrites the shipped layout, so the running artifact is no longer the published jar.

Acceptance criteria

  • Image builds and boots with an empty /modules exactly as before (clean boot log, all ITs unaffected).
  • Dropping an AOT module jar (compiled classes + META-INF/dirigible/<project>/.compiled marker + payload) into /modules results on boot in: the payload expanded into registry/public/<project>/, the log line Registered [N] class(es) from AOT compiled module(s) on the classpath, the module's REST controller(s) serving requests — and zero javac activity for that module.
  • The mechanism is documented (Dockerfile comment + a short section in the engine-java documentation): what goes into /modules, the LOADER_PATH override, and the relationship to feat(engine-java): classpath loading of AOT compiled modules (no runtime javac) #6400.

References

  • feat(engine-java): classpath loading of AOT compiled modules (no runtime javac) #6400 — classpath loading of AOT compiled modules (merged)
  • build/application/Dockerfile — current JarLauncher entrypoint
  • components/engine/engine-java/.../runtime/CompiledModuleClassProvider.java — the consumer contract (.compiled markers)
  • Spring Boot 3 PropertiesLauncher (org.springframework.boot.loader.launch.PropertiesLauncher, loader.path / LOADER_PATH)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions