You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a design proposal for discussion — not an accepted plan or committed work. It sketches a direction and its trade-offs so the approach can be reviewed before anyone implements it. Scope, DSL/XML surface, and naming are all open to change. Depends on #977.
Summary
Add first-class support for -H:Preserve (keeping classes reachable that closed-world analysis would otherwise drop) by reusing the ArtifactSelection model from #977 — no new selection vocabulary. The build-tool value is resolving dependency coordinates to path= entries; the all / bare module=/package= cases remain on the build-args pass-through.
The genuinely build-tool part — "preserve everything from dependency com.acme:extension and its closure" — cannot be written as a static buildArgs entry, because path=<jar> is computed by dependency resolution. That is the justification for a first-class surface; without resolution there is nothing to add over pass-through.
There is currently no tracking issue and no code for Preserve in NBT — it is greenfield on both. Introducing it after#977 means it reuses a proven model rather than inventing a parallel one.
Proposal
Reuse ArtifactSelection and add a renderPreserve(ArtifactSelection) in common/. Surface the same selector block used by layer contents:
Both preserve blocks deserialize into the same ArtifactSelection bean and render through the same common code path (so escaping and arg-file conversion are identical).
NGOAL-no-flag-mirroring: first-class only for the dependency-selection dimension (needs resolution); all and bare module/package ride buildArgs/<buildArgs>. Because the selection model is shared with layers, this judgment call is made once and inherited.
renderPreserve(ArtifactSelection) in common/ + unit tests.
Gradle preserve { } block on binaries.
Maven <preserve> config on the compile goals.
Functional test: preserve an individual dependency + its closure, verify a type that analysis would drop survives.
Open question
Scope Preserve per-binary only (matches how it's used), or also allow it on a created layer's contents? Recommend per-binary first; revisit if a use case appears.
Note
This is a design proposal for discussion — not an accepted plan or committed work. It sketches a direction and its trade-offs so the approach can be reviewed before anyone implements it. Scope, DSL/XML surface, and naming are all open to change. Depends on #977.
Summary
Add first-class support for
-H:Preserve(keeping classes reachable that closed-world analysis would otherwise drop) by reusing theArtifactSelectionmodel from #977 — no new selection vocabulary. The build-tool value is resolving dependency coordinates topath=entries; theall/ baremodule=/package=cases remain on the build-args pass-through.Motivation
-H:PreservesharesLayerCreate's grammar exactly:The genuinely build-tool part — "preserve everything from dependency
com.acme:extensionand its closure" — cannot be written as a staticbuildArgsentry, becausepath=<jar>is computed by dependency resolution. That is the justification for a first-class surface; without resolution there is nothing to add over pass-through.There is currently no tracking issue and no code for Preserve in NBT — it is greenfield on both. Introducing it after #977 means it reuses a proven model rather than inventing a parallel one.
Proposal
Reuse
ArtifactSelectionand add arenderPreserve(ArtifactSelection)incommon/. Surface the same selector block used by layercontents:binaries { main { preserve { dependencies("com.acme:extension") // resolved → path= (the build-tool value) packages("com.acme.plugins") // dynamically-loaded plugin package // all() // = -H:Preserve=all } } }Both
preserveblocks deserialize into the sameArtifactSelectionbean and render through the same common code path (so escaping and arg-file conversion are identical).Spec alignment
Spec links pinned to commit
e067164.alland bare module/package ridebuildArgs/<buildArgs>. Because the selection model is shared with layers, this judgment call is made once and inherited.common/, symmetric Gradle/Maven surfaces.Depends on
ArtifactSelectiontype and the plugin-side coordinate→path resolution. Should not start until Proposal: Uplift the layers configuration model (typed model, shared selection, Gradle+Maven parity) #977's selection model exists.Related
ArtifactSelection. Worth cross-linking so the shared model isn't scoped to just layers+preserve.Deliverables
renderPreserve(ArtifactSelection)incommon/+ unit tests.preserve { }block on binaries.<preserve>config on the compile goals.Open question
Scope Preserve per-binary only (matches how it's used), or also allow it on a created layer's
contents? Recommend per-binary first; revisit if a use case appears.