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 5e49398aa7 Add missing 10.0.0 release-note entries (childrenDefs,
matcher List change, Json5 freeze fix, CodeQL hardening)
5e49398aa7 is described below
commit 5e49398aa7bd66fa523f3bb3c63a97f286fc9fe8
Author: James Bognar <[email protected]>
AuthorDate: Sun Jul 26 10:28:19 2026 -0400
Add missing 10.0.0 release-note entries (childrenDefs, matcher List change,
Json5 freeze fix, CodeQL hardening)
- Document @Rest(childrenDefs=@Child(...)) host-side child seeding
- Document RestOpContext matcher getters changing from arrays to List
(TODO-238)
- Document Json5Map/Json5List frozen-instance mutation-surface fix
- Document CodeQL alert remediation (AuthFilter, PlainTextPojoProcessor,
XmlReader, ReDoS hardening)
Co-authored-by: Cursor <[email protected]>
---
pages/release-notes/10.0.0.md | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/pages/release-notes/10.0.0.md b/pages/release-notes/10.0.0.md
index a523aa7865..e5bff213e1 100644
--- a/pages/release-notes/10.0.0.md
+++ b/pages/release-notes/10.0.0.md
@@ -326,6 +326,23 @@ public class ApiResource extends BasicRestServlet { ... }
Internally this also normalized mixin discovery (one `ResolvedMixin` carrier
for both bare and rich forms) and replaced the `RestContext.Args` boolean
`mixinContext` flag with a typed `ContextKind` discriminator
(`Root`/`Child`/`Mixin`). See [Host-side overrides with
`@Mixin`](/docs/topics/RestServerMixinSubContexts#host-side-overrides-with-mixin-1000).
+### Host-side child seeding — `@Rest(childrenDefs=@Child(...))`
+
+Children are deliberately **isolated** from the host's resolution chain — a
child's serializers, parsers, guards, call logger, etc. resolve against its own
`RestContext` only, never inherited from the parent. New in 10.0.0, the
`@Rest(childrenDefs=@Child(...))` attribute lets a host **seed** a curated set
of settings onto a routed child's otherwise-isolated context, without editing
the child class — the child-resource analog of the
`@Rest(mixinDefs=@Mixin(...))` attribute above:
+
+```java
+@Rest(childrenDefs=@Child(type=AdminResource.class,
callLogger=StructuredJsonLogger.class, guards=AdminBearerGuard.class))
+public class ApiResource extends BasicRestServlet { ... }
+```
+
+- **Additive / non-breaking.** `childrenDefs` coexists with the existing
`children=Class<?>[]`; a `@Child(type=X.class)` with no seed members is exactly
equivalent to a bare `children=X.class` entry, and if both name the same class
the rich entry wins (the bare entry is upgraded in place).
+- **Two seed-semantics buckets** — since children are isolated by design, a
seed can't "override" an inherited chain the way a `@Mixin` override does; it
can only add to or fill gaps in the child's own config: **additive-security**
(`guards`, `converters`, `roleGuard`, `rolesDeclared`) — the host's
contribution is added alongside the child's own (list-shaped members prepend;
the two role-based members AND-stack) and can never be removed or weakened by
the child; **child-wins scalars** (` [...]
+- **`noInherit` cuts the seed too.** A child's own
`@Rest(noInherit="<property>")` suppresses the corresponding host-seeded value,
for either bucket, so the child always stays in full control of its own
configuration.
+- **Survives lazy materialization** — a seed applies to a
`@Rest(lazyChildren="true")` child on first request exactly as it would to an
eagerly-built one.
+- **Not (yet) seedable:** `defaultAccept`/`defaultContentType` were originally
planned but dropped before shipping — they resolve through a shared first-wins
mechanism that would make the seed win over the child's own value, the opposite
of every other child-wins scalar's contract.
+
+See [Host-side seeding with
`@Child`](/docs/topics/ChildResources#host-side-seeding-with-child-1000) and
[REST Server — Children vs Mixins](/docs/topics/RestServerChildrenVsMixins).
+
### Custom observations + one-dependency OTLP export + log correlation
Juneau 10.0 extends its request-boundary observability to cover custom
(non-request) observations, ships a single OTLP export bundle, and adds
OpenTelemetry trace-id log correlation — all keeping the explicit-over-magic,
off-by-default contract (no classpath auto-configuration).
@@ -631,6 +648,15 @@ constants (see Breaking Changes below). The
[Marshallers](/docs/topics/Marshalle
- **Fixed RRPC method calls never dispatching over POST.** Every HTTP POST to
an `@RestOp(method="RRPC")` operation previously returned a 404 instead of
reaching the target method. `RrpcRestOpSession` derived the RRPC method key by
splitting the request path on the last `/`, but RRPC keys are of the form
`methodName/(paramTypes)` and themselves contain a `/`, so the method name was
stripped off and the lookup always fell through to `NotFound`. The key is now
derived from the already-comp [...]
+- **Fixed `Json5Map` / `Json5List` frozen (`.unmodifiable()`) instances still
being mutable through several paths.** The `Unmodifiable` variants of
`Json5Map` and `Json5List` (`juneau-marshall`) only overrode a subset of the
mutator surface — `put(String,Object)`/`remove(Object)` for the map,
`add(int,·)`/`remove(int)`/`set(int,·)` for the list — so a caller holding a
supposedly-frozen instance could still mutate it through the remaining paths:
`clear()`, `putAll`/`addAll`, `compute*`/`m [...]
+
+- **Security hardening — CodeQL alert remediation.** A CodeQL
security-scanning pass resolved a batch of code-scanning alerts, including two
response-content changes and one parser-hardening change that are user-visible:
+ - **`AuthFilter`** now returns a generic `Unauthorized` response body on an
authentication failure instead of exposing failure detail to the client; the
detail is still recorded server-side via logging.
+ - **`PlainTextPojoProcessor`** now emits a generic status message for
`Throwable` results in production rather than the exception detail, gated by
the existing `renderResponseStackTraces` opt-in (dev/debug behavior is
unchanged).
+ - **`XmlReader`**'s non-validating parse path now disables DTD processing
outright, closing a residual XXE surface (external-entity resolution was
already disabled).
+
+ A related set of ReDoS-hardening fixes (bounded/escaped regex handling in
`HttpPartSchema`, `LogEntryFormatter`, and the request-routing
`UrlPathMatcher`) landed in the same sweep. **Migration:** none for normal
usage; an application that displayed unauthorized-request detail to end users,
or that parsed XML relying on DTD processing on the non-validating path, will
see the new generic/hardened behavior.
+
### Breaking Changes
- **`juneau-my-jetty-microservice` removed.** The template-project module has
been retired in favor of the new `JettyMicroservice` facade + bundled defaults
in `juneau-microservice-jetty`. See the New Features section above for
migration guidance.
@@ -662,6 +688,8 @@ constants (see Breaking Changes below). The
[Marshallers](/docs/topics/Marshalle
- Both `MediaType` overloads now guard `null` and return `Optional.empty()`
(previously `ParserSet.getParserMatch(MediaType)` threw an NPE on a `null`
argument).
- Migration: unwrap with `.map(...)` / `.orElseThrow(...)` /
`.ifPresent(...)`, or `.orElse(null)` to preserve a prior null contract. For
the HTTP-server direction, throwing the status-correct exception is idiomatic —
`NotAcceptable` (406) for a failed `Accept`/serializer lookup and
`UnsupportedMediaType` (415) for a failed `Content-Type`/parser lookup. The
next-gen (Beta) `RestClient.getSerializerForMediaType(String)`,
`getParserForMediaType(String)`, and `getMatchingParser(String)` l [...]
+- **`RestOpContext` matcher getters changed from arrays to `List`
(TODO-238).** `RestOpContext.getPathMatchers()`, `getOptionalMatchers()`, and
`getRequiredMatchers()` previously returned raw arrays (`UrlPathMatcher[]` /
`RestMatcher[]` respectively); as of 10.0.0 they return an immutable, cached
`List` instead (`List<UrlPathMatcher>` / `List<RestMatcher>`), closing a
mutable-state-exposure hole where a caller holding the returned array could
corrupt the op context's routing/matcher stat [...]
+
- **Next-gen (Beta) `RestClient` no longer falls back to JSON implicitly
(behavioral change).** The next-generation
`org.apache.juneau.rest.client.RestClient` previously treated a
fully-unconfigured client as "JSON in / JSON out" and also used a lone
registered parser/serializer regardless of media type. Both implicit behaviors
are **removed**: content negotiation now resolves a parser/serializer **only**
via an exact media-type match or an explicitly-configured default, otherwise it
res [...]
- New opt-in builder knobs restore the old behavior deliberately:
`RestClient.Builder.defaultParser(Parser)` and
`RestClient.Builder.defaultSerializer(Serializer)` (e.g.
`.defaultParser(JsonParser.DEFAULT).defaultSerializer(JsonSerializer.DEFAULT)`).
- Resolution precedence is now: exact media-type match →
explicitly-configured default → none.