This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch docs
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/docs by this push:
     new 77b9e2fc3b docs: GraalVM native-image feasibility verdict + Docker 
layering guidance
77b9e2fc3b is described below

commit 77b9e2fc3b89d8bc7b136608d225658f340ee98d
Author: James Bognar <[email protected]>
AuthorDate: Fri Jun 19 09:31:08 2026 -0400

    docs: GraalVM native-image feasibility verdict + Docker layering guidance
---
 pages/release-notes/10.0.0.md                   |  4 +++
 pages/topics/17.02.NativeImageAndLayeredJars.md | 43 +++++++++++++++++++++++++
 sidebars.ts                                     |  5 +++
 3 files changed, 52 insertions(+)

diff --git a/pages/release-notes/10.0.0.md b/pages/release-notes/10.0.0.md
index e9408bc399..75f203bb08 100644
--- a/pages/release-notes/10.0.0.md
+++ b/pages/release-notes/10.0.0.md
@@ -202,6 +202,10 @@ A reactor-consistency guard 
(`scripts/check-bom-completeness.py`, wired into the
 
 See the new [Dependency Management (BOM & 
Bundles)](/docs/topics/DependencyManagement) topic page for usage and the full 
explicit-over-magic rationale.
 
+#### GraalVM native-image feasibility verdict + Docker layering guidance
+
+A feasibility assessment of GraalVM **native-image** support for Juneau's 
reflection-heavy marshalling/bean core landed a **CONDITIONAL GO** verdict: all 
reflection is funnelled through one wrapper layer 
(`org.apache.juneau.commons.reflect.*`, single `setAccessible()` choke point) 
with no `Unsafe`/`MethodHandle`/bytecode generation, and the 
`BeanContext`/`ClassMeta` model already computes the exact member set 
reachability metadata needs — making a Juneau-authored metadata emitter realist 
[...]
+
 ### juneau-petstore (new module family)
 
 Three new modules under a top-level `juneau-petstore/` aggregator together 
form the canonical Juneau petstore showcase application.  The legacy 
`juneau-examples-rest{,-jetty,-springboot,-jetty-ftest}` family of modules has 
been retired in this release in favor of the petstore family — see the 
**Breaking Changes** section below.
diff --git a/pages/topics/17.02.NativeImageAndLayeredJars.md 
b/pages/topics/17.02.NativeImageAndLayeredJars.md
new file mode 100644
index 0000000000..19c2fbe9ea
--- /dev/null
+++ b/pages/topics/17.02.NativeImageAndLayeredJars.md
@@ -0,0 +1,43 @@
+---
+title: "GraalVM Native Image & Docker Layering"
+slug: NativeImageAndLayeredJars
+---
+
+This page covers two packaging concerns for Juneau applications: **Docker 
image layering** (a concrete recommendation you can apply today) and **GraalVM 
native-image** support (a feasibility assessment with a forward plan).
+
+## Docker image layering
+
+Juneau itself ships **libraries**, not runnable applications, so there is no 
Juneau-side fat-jar to layer. Layering happens in *your* deployable application 
image. Two practical levers:
+
+- **Spring Boot apps** — `spring-boot-maven-plugin`'s `repackage` goal 
produces a [layered 
jar](https://docs.spring.io/spring-boot/reference/packaging/efficient.html) by 
default (since Spring Boot 2.4), separating slow-changing dependency layers 
from your fast-changing application classes. Combined with a multi-stage 
Dockerfile using `java -Djarmode=tools -jar app.jar extract --layers`, Docker 
caches the dependency layer across rebuilds. The Juneau Spring Boot petstore 
sample is built this way.
+- **Embedded-Jetty / plain-jar apps** — order your Dockerfile `COPY` steps 
coarsest-changing first: copy the dependency jars (which include the stable 
Juneau artifacts) in an earlier layer than your application jar, so a code-only 
change re-uploads only the small application layer. The external [starter 
projects](/docs/topics/StarterProjects) demonstrate this Dockerfile shape.
+
+Depending on Juneau through the version-aligned [BOM and curated 
bundles](/docs/topics/DependencyManagement) keeps the dependency layer stable 
and reproducible across rebuilds, which is what makes the cache hit reliable.
+
+## GraalVM native-image — feasibility verdict
+
+Juneau's marshalling/bean core is reflection-heavy, so native-image 
(closed-world AOT) support is non-trivial. A feasibility assessment was 
performed against the reflective source; the verdict is **CONDITIONAL GO**.
+
+### Why "conditional go", not "no-go"
+
+All of Juneau's reflection flows through a single wrapper layer — 
`org.apache.juneau.commons.reflect.*` (`ClassInfo` / `MethodInfo` / `FieldInfo` 
/ `ConstructorInfo`) with one `setAccessible()` choke point in `AccessibleInfo` 
— and there is **no `sun.misc.Unsafe`, no `MethodHandle`/`VarHandle`, and no 
bytecode generation** anywhere in main source. The blockers are the *standard* 
native-image reflection blockers, not anything pathological. Critically, the 
same `BeanContext` / `BeanMeta` / [...]
+
+### The hard blockers (all standard, all addressable)
+
+1. **Open-world bean reflection** — every marshalled bean's full member set 
must be registered; application bean types are unknowable at Juneau-build time. 
There is no "zero-config native Juneau" — consumers always need a generation 
step.
+2. **User-supplied dynamic-proxy interface sets** (`@Remote` clients, 
interface beans) — proxy metadata can't be derived from Juneau's bytecode; it 
comes from the GraalVM tracing agent or explicit declaration.
+3. **`_type` dictionary class resolution** via `Class.forName` — classes 
reachable only through a serialized `_type` string are invisible to static 
analysis and must be registered by name.
+4. **Reflective swap/converter/DI instantiation** through `BeanInstantiator`.
+5. **Classpath resource + NLS `ResourceBundle` loading** — broad but low-risk 
(regex resource includes cover it).
+
+SPIs / `ServiceLoader` usage, despite intuition, is the *easiest* category — 
finite and statically known.
+
+### Recommended path (committed follow-on)
+
+The maintainer-approved direction is **option (b)**: a native-image-ready 
`juneau-marshall` **core** (JSON/XML/HTML/UON + swaps + dictionaries), driven 
by a Juneau-authored reachability-metadata emitter built on `BeanContext` 
introspection, with the GraalVM **tracing agent** covering the 
statically-invisible parts (`@Remote`/interface-bean proxies, `_type` 
dictionary classes). Target the modern unified `reachability-metadata.json` 
format, delivered as a **Maven plugin goal / module** the [...]
+
+The REST server (embedded Jetty/Tomcat, `ServletContainerInitializer`, 
transport providers) is **deferred** — most of its residual native-image risk 
lives in third-party dependencies, not Juneau's own code.
+
+Rough effort: a minimal single-bean JSON round-trip to native is **S** (~1–3 
days); a generally-usable native marshalling core is **L** (~3–6 weeks); the 
full framework including `@Remote` proxies + REST server is **XL** and out of 
scope.
+
+> This assessment is a **feasibility verdict**, not a shipped feature. The 
native-image emitter is tracked as a dedicated committed follow-on; 
native-image builds of Juneau are not yet supported.
diff --git a/sidebars.ts b/sidebars.ts
index bfe4e2e473..f74ac0f497 100644
--- a/sidebars.ts
+++ b/sidebars.ts
@@ -2121,6 +2121,11 @@ const sidebars: SidebarsConfig = {
                                                        id: 
'topics/17.01.DependencyManagement',
                                                        label: '17.1. 
Dependency Management (BOM & Bundles)',
                                                },
+                                               {
+                                                       type: 'doc',
+                                                       id: 
'topics/17.02.NativeImageAndLayeredJars',
+                                                       label: '17.2. GraalVM 
Native Image & Docker Layering',
+                                               },
                                        ],
                                },
                                {

Reply via email to