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 867c3e344a docs: add @Value framework-internal adoption notes
867c3e344a is described below
commit 867c3e344a71adb7a6a394d24cc11cff28374a66
Author: James Bognar <[email protected]>
AuthorDate: Wed May 27 07:08:01 2026 -0400
docs: add @Value framework-internal adoption notes
Co-authored-by: Cursor <[email protected]>
---
pages/release-notes/9.5.0.md | 71 ++++++++++++++++++++++
pages/topics/02.21.07.ValueFrameworkInternal.md | 81 +++++++++++++++++++++++++
sidebars.ts | 5 ++
3 files changed, 157 insertions(+)
diff --git a/pages/release-notes/9.5.0.md b/pages/release-notes/9.5.0.md
index 7e00d28e20..b70d27d7b7 100644
--- a/pages/release-notes/9.5.0.md
+++ b/pages/release-notes/9.5.0.md
@@ -2050,6 +2050,17 @@ Note: Apache Jena 6.0 requires Java 21 and will be
adopted when the project move
### juneau-core
+#### `BctConfiguration` defaults migrated to `@Value` (TODO-92)
+
+- `BctConfiguration` now exposes a static nested `Defaults` class whose two
boolean fields
+ (`sortMaps`, `sortCollections`) are populated by concat-form `@Value`
annotations:
+ `@Value("${" + BCT_SORT_MAPS + ":false}")` / `@Value("${" +
BCT_SORT_COLLECTIONS + ":false}")`.
+ A `BctConfiguration.defaults()` static factory routes construction through
+ `BeanInstantiator`, so the defaults respect the standard `Settings`
precedence chain.
+- The two public constants (`BCT_SORT_MAPS`, `BCT_SORT_COLLECTIONS`) are
**kept**, since they
+ have external production consumers and heavy Javadoc as part of the BCT
public API. See
+ [@Value Framework-Internal Adoption](../topics/ValueFrameworkInternal.md).
+
#### ArrayUtils Deprecation
`ArrayUtils` has been deprecated in favor of `CollectionUtils`. All array
utility methods have been migrated to `CollectionUtils`, which now provides a
single location for both array and collection operations. `ArrayUtils` methods
delegate to their `CollectionUtils` counterparts and will remain available
during the deprecation period.
@@ -2210,6 +2221,38 @@ String name
### juneau-rest-server
+#### Framework-internal `@Value` adoption (TODO-92)
+
+Framework-internal config readers in `juneau-rest-server` now route through
the `@Value`
+seam introduced in TODO-79, replacing the hand-rolled `env(...)` /
`System.getProperty(...)`
+calls that were deliberately left in place by FINISHED-79 Phase 6:
+
+- **`CallLogger.Builder`** — five env reads
(`juneau.restLogger.{logger,enabled,requestDetail,
+ responseDetail,level}`) replaced by `@Value` fields. The builder is now
created via
+ `BeanInstantiator.of(Builder.class, beanStore).run()`. The `Logger` field is
populated by an
+ `@Inject` method (`initLoggerFromName`) that takes a
`@Value("${juneau.restLogger.logger:global}")
+ String` and lazily calls `Logger.getLogger(...)`.
+- **`RestContext`** — 15 env-driven defaults that flow into the
`mergeReplacedStringAttribute` /
+ `mergeReplacedBooleanAttribute` pipelines (`debugDefault`, `debugLevel`,
`allowedHeaderParams`,
+ `allowedMethodHeaders`, `allowedMethodParams`, `disableContentParam`,
`renderResponseStackTraces`,
+ `problemDetails`, `virtualThreads`, `eagerInit`, `clientVersionHeader`,
`uriRelativity`,
+ `uriAuthority`, `uriContext`, `uriResolution`) are now `@Value`-annotated
private fields
+ populated by a `ClassInfo.of(this).inject(this, beanStore)` call inside the
constructor.
+- **`RestOpContext`** — two env reads (`RestContext.defaultCharset`,
`RestContext.maxInput`)
+ replaced by `@Value` fields, also injected via `ClassInfo.inject` in the
constructor.
+- **`BasicVersionResource.Builder`** — `System.getProperty("java.version")`
replaced by
+ `@Value("${java.version:Unknown}")`, builder constructed via
`BeanInstantiator`.
+
+**Breaking change — `CallLogger.SP_*` constants deleted.** Five public
constants on
+`CallLogger` were removed outright (no `@Deprecated` shim):
+
+- `SP_logger`, `SP_enabled`, `SP_requestDetail`, `SP_responseDetail`,
`SP_level`
+
+Code that imported these constants directly must inline the literal property
name string —
+see [@Value Framework-Internal Adoption](../topics/ValueFrameworkInternal.md)
for the
+mapping. The Javadoc cross-references that used to read `{@link
CallLogger#SP_xxx "..."}`
+have all been rewritten to plain `<js>"..."</js>` literal text.
+
#### `RestContext` wires its `Config` into `Settings` (TODO-79)
- `RestContext`'s constructor now installs a `ConfigPropertySource` for the
resource-scoped `Config`
@@ -3335,6 +3378,16 @@ See [REST Server — Conditional-GET / ETag
Helpers](/docs/topics/RestServerCond
bean built through `BeanInstantiator` — resolves against the microservice
config without an
explicit lookup call.
+#### `juneau.workingDir` migrated to `@Value` (TODO-92)
+
+- The `juneau.workingDir` env-driven default on `Microservice.Builder` is now
populated by an
+ `@Inject`-annotated initializer (`initWorkingDirFromEnv`) that takes a
+ `@Value("${juneau.workingDir}") String` parameter. The builder is now
constructed via
+ `BeanInstantiator.of(Builder.class, beanStore).run()`. Existing programmatic
+ `Microservice.create().workingDir(...)` callers are unaffected — the
`@Inject` initializer
+ only sets `workingDir` when it has not already been assigned. See
+ [@Value Framework-Internal Adoption](../topics/ValueFrameworkInternal.md).
+
#### Module Renamed (TODO-36)
The `juneau-microservice-core` Maven artifact has been **renamed** to
`juneau-microservice`. The aggregator pom is now
@@ -3441,6 +3494,15 @@ public View hello(@Path String name) {
### juneau-microservice-jetty
+#### `JettyServerComponent` env reads migrated to `@Value` (TODO-92)
+
+- `JettyServerComponent` previously called `env("availablePort")` and
`env("juneau.serverPort")`
+ to skip an empty fallback during port resolution. These reads are now
`@Value("${availablePort}")
+ Optional<String> availablePortEnv` and `@Value("${juneau.serverPort}")
Optional<String>
+ serverPortEnv` fields populated by `ClassInfo.of(this).inject(this, store)`
inside
+ `onStart(Microservice)`. Behavior is unchanged. See
+ [@Value Framework-Internal Adoption](../topics/ValueFrameworkInternal.md).
+
#### `HealthProbeConfiguration` (TODO-65)
`juneau-microservice-jetty` now ships `HealthProbeConfiguration`, an opt-in
`@Configuration` module
@@ -3818,6 +3880,15 @@ See [juneau-bean-mcp](/docs/topics/JuneauBeanMcp) for
the full topic.
### juneau-rest-server-jwt (new module)
+#### `jwksCacheTtl` migrated to `@Value` (TODO-92)
+
+- `JwtTokenValidator.Builder` now resolves its default `jwksCacheTtl` (5
minutes) through
+ `@Value("${juneau.jwt.jwksCacheTtl:PT5M}") Duration jwksCacheTtl` instead of
a hand-rolled
+ initializer. The static factory now routes through `BeanInstantiator`,
allowing the value
+ to flow through the standard `Settings` precedence chain (system property
→ env var →
+ registered `PropertySource` → `Settings.setGlobal`). Behavior is
identical when no
+ override is set. See [@Value Framework-Internal
Adoption](../topics/ValueFrameworkInternal.md).
+
A new opt-in REST module, `juneau-rest-server-jwt`, adds JWT bearer-token
verification to `juneau-rest-server` without bleeding the
[nimbus-jose-jwt](https://connect2id.com/products/nimbus-jose-jwt) dependency
into the core. The nimbus dep is declared in `provided` scope on the module's
POM, so consumers explicitly pick the nimbus version they want.
`mvn -pl juneau-rest/juneau-rest-server dependency:tree | grep -i nimbus`
returns nothing — the containment requirement is verified at build time. See
[REST Server — AuthN Guards § JWT
verification](/docs/topics/RestServerAuthGuards) for the full reference.
diff --git a/pages/topics/02.21.07.ValueFrameworkInternal.md
b/pages/topics/02.21.07.ValueFrameworkInternal.md
new file mode 100644
index 0000000000..9eab808bf5
--- /dev/null
+++ b/pages/topics/02.21.07.ValueFrameworkInternal.md
@@ -0,0 +1,81 @@
+---
+title: "@Value Framework-Internal Adoption"
+slug: ValueFrameworkInternal
+---
+
+This page documents the framework-internal sites that read configuration
through the
+`@Value` seam (introduced in 9.5.0). It is a reference for users who:
+
+- Used to import the deleted `CallLogger.SP_xxx` constants directly.
+- Want to know which framework defaults are now `@Value`-driven (and therefore
overridable
+ through the standard `Settings` precedence chain — system properties,
environment
+ variables, registered `PropertySource`s, and `Settings.setGlobal(...)`).
+
+## Migration outcome
+
+In 9.5.0 (TODO-92) the following framework-internal config readers were
rewritten on top of
+the [`@Value` annotation](./ValueAnnotationBasics.md) and `BeanInstantiator`:
+
+| Class | Field / Property | Inline expression |
+|---|---|---|
+| `CallLogger.Builder` | `enabled` | `${juneau.restLogger.enabled:ALWAYS}` |
+| `CallLogger.Builder` | `requestDetail` |
`${juneau.restLogger.requestDetail:STATUS_LINE}` |
+| `CallLogger.Builder` | `responseDetail` |
`${juneau.restLogger.responseDetail:STATUS_LINE}` |
+| `CallLogger.Builder` | `level` | `${juneau.restLogger.level:OFF}` |
+| `CallLogger.Builder` | `logger` (name) |
`${juneau.restLogger.logger:global}` |
+| `RestContext` | env-driven defaults for `debugDefault`, `debugLevel`,
`allowedHeaderParams`, `allowedMethodHeaders`, `allowedMethodParams`,
`disableContentParam`, `renderResponseStackTraces`, `problemDetails`,
`virtualThreads`, `eagerInit`, `clientVersionHeader`, `uriRelativity`,
`uriAuthority`, `uriContext`, `uriResolution` | `${RestContext.<name>:default}`
(15 sites) |
+| `RestOpContext` | env-driven defaults for `defaultCharset`, `maxInput` |
`${RestContext.defaultCharset:UTF-8}` / `${RestContext.maxInput:100000000}` |
+| `BasicVersionResource.Builder` | `javaVersionDefault` |
`${java.version:Unknown}` |
+| `Microservice.Builder` | `juneau.workingDir` | `${juneau.workingDir}` (via
`@Inject` initializer) |
+| `JettyServerComponent` | `availablePort`, `juneau.serverPort` |
`${availablePort}` / `${juneau.serverPort}` (`Optional<String>` fields) |
+| `JwtTokenValidator.Builder` | `jwksCacheTtl` |
`${juneau.jwt.jwksCacheTtl:PT5M}` |
+| `BctConfiguration.Defaults` | `sortMaps`, `sortCollections` | concat-form:
`${" + BCT_SORT_MAPS + ":false}` / `${" + BCT_SORT_COLLECTIONS + ":false}` |
+
+Every one of these sites used to call `env(...)` or `System.getProperty(...)`
directly. The
+new flow routes through `BeanInstantiator` and inherits the standard
`Settings` lookup chain
+documented in [`@Value` Annotation Basics](./ValueAnnotationBasics.md).
+
+## Static-factory pattern
+
+The five builders that did not previously flow through `BeanInstantiator` now
do, via a
+small static factory that hands the builder off to
`BeanInstantiator.of(Builder.class).run()`:
+
+```java
+public static Builder create(BeanStore beanStore) {
+ return BeanInstantiator.of(Builder.class, beanStore).run();
+}
+```
+
+Builders affected: `CallLogger`, `BasicVersionResource`, `Microservice`,
`JwtTokenValidator`,
+plus the static-utility nested class `BctConfiguration.Defaults`.
+
+For classes that are not constructed through `BeanInstantiator` (because
they're built by
+the framework — `RestContext`, `RestOpContext`, `JettyServerComponent`), the
constructor /
+lifecycle hook calls `ClassInfo.of(this).inject(this, beanStore)` after the
bean store is
+populated, which performs the same `@Value` field injection on the existing
instance.
+
+## SP_xxx constant removal (BREAKING)
+
+Five `SP_xxx` system-property name constants were deleted outright (no
`@Deprecated` shim).
+If your code imports any of these directly, you must inline the literal string:
+
+| Deleted constant | Replacement string literal |
+|---|---|
+| `CallLogger.SP_logger` | `"juneau.restLogger.logger"` |
+| `CallLogger.SP_enabled` | `"juneau.restLogger.enabled"` |
+| `CallLogger.SP_requestDetail` | `"juneau.restLogger.requestDetail"` |
+| `CallLogger.SP_responseDetail` | `"juneau.restLogger.responseDetail"` |
+| `CallLogger.SP_level` | `"juneau.restLogger.level"` |
+
+The `BctConfiguration.BCT_SORT_MAPS` and `BCT_SORT_COLLECTIONS` constants were
**kept** —
+they are part of the public BCT API and have external production consumers;
they're now
+referenced from `@Value` annotations via concat form.
+
+## What this does *not* change
+
+The `mergeReplacedStringAttribute` precedence inside `RestContext` — where
`@Rest`
+annotation values from the resource hierarchy override the env-driven default
if non-blank —
+is unchanged. The `DefaultConfig` class (whose `@Rest(...)` defaults pull from
`$S{j.<name>,
+$E{J_<NAME>,<fallback>}}` SVL chains) still wins over the new `@Value` field
for properties
+whose `DefaultConfig` fallback is non-blank. The `@Value`-driven default only
takes effect
+in the same situations the previous `env(...)` default did.
diff --git a/sidebars.ts b/sidebars.ts
index bd7c7423e9..e0110a361a 100644
--- a/sidebars.ts
+++ b/sidebars.ts
@@ -352,6 +352,11 @@ const sidebars: SidebarsConfig = {
id:
'topics/02.21.06.ValueAnnotationBasics',
label:
'2.21.6. @Value Annotation Basics',
},
+ {
+ type:
'doc',
+ id:
'topics/02.21.07.ValueFrameworkInternal',
+ label:
'2.21.7. @Value Framework-Internal Adoption',
+ },
],
},
{