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 029dc27a5a Add 10.0.0 release notes for LogRecord source-detection
removal + null-tolerant fluent assertions
029dc27a5a is described below
commit 029dc27a5a8b4d6bbe8197e6e9e24b4a038ad110
Author: James Bognar <[email protected]>
AuthorDate: Thu Jul 23 09:17:04 2026 -0400
Add 10.0.0 release notes for LogRecord source-detection removal +
null-tolerant fluent assertions
Documents two behavior changes that landed in the main juneau repo:
LogRecord.formatted()
dropping the {source}/{class}/{method} placeholders (with the resulting
%N$s index shift),
and the fluent request/response header/param assertions no longer throwing
NPE on a null
value.
Co-authored-by: Cursor <[email protected]>
---
pages/release-notes/10.0.0.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/pages/release-notes/10.0.0.md b/pages/release-notes/10.0.0.md
index 215da1ab74..e77d9a6faf 100644
--- a/pages/release-notes/10.0.0.md
+++ b/pages/release-notes/10.0.0.md
@@ -680,6 +680,8 @@ _TBD — to be filled in as development continues._
- **i18n unaffected:** `Messages.getString(key, args)` (resource-bundle
i18n) and `LogRecord.getMessage()` (logging) continue to render
MessageFormat-style `.properties`/log patterns — they now route through `mf()`
internally, so `{0}`-style entries in your resource bundles keep working
exactly as before. Juneau's `Logger` MessageFormat-style logging is likewise
unchanged.
- The dual-syntax `StringFormat` engine still exists and remains directly
usable (`StringFormat.of(...)`) for callers that want both grammars in one
pattern; only the `f()`/`fs()`/`StringUtils.format` entry points were narrowed
to printf.
+- **`LogRecord.formatted(...)` no longer supports source-detection
placeholders (behavioral change).**
`org.apache.juneau.commons.logging.LogRecord` removed its unreliable JUL-style
stack-walk source detection — the `findSource()` walk and the
`getSourceClassName()` / `getSourceMethodName()` overrides — along with the
`{source}`, `{class}`, and `{method}` named placeholders in
`formatted(String)`. As a result, positional `%N$s` `Formatter`-style
specifiers passed to `formatted(...)` shif [...]
+
- **Serializer/Parser I/O narrowed to streams — `File` and `StringBuilder` no
longer accepted (TODO-248).** The core serialize/parse I/O surface now accepts
only `Reader` / `Writer` / `InputStream` / `OutputStream` (plus the existing
scalar `String` / `byte[]` / `CharSequence` shortcut forms). The `File` and
`StringBuilder` `instanceof` branches were removed from the internal
`SerializerPipe` / `ParserPipe` I/O plumbing, so passing a `File` or
`StringBuilder` to `Serializer.write(Object, [...]
- The same narrowing applies to the **token/record streaming** surface
(TODO-248 "Option B"): `writeTokens(...)` / `readTokens(...)` /
`writeRecords(...)` / `writeArrayRecords(...)` (and the `Marshaller`
`ofTokens`/`ofRecords`/`ofArrayRecords` shortcuts) no longer accept
`File`/`StringBuilder` either — the `*TokenWriter.forOutput(...)` factories
(JSON / JSONL / CBOR / MsgPack) are stream-only.
- **Migration — `File`:** wrap it yourself.
@@ -729,6 +731,8 @@ _TBD — to be filled in as development continues._
- **`BasicHeader.hashCode()` is now consistent with `equals(Object)`
(behavioral change).** `org.apache.juneau.http.classic.header.BasicHeader`
(`juneau-rest-common-classic`) previously computed `equals(Object)` from `name`
+ value while `hashCode()` returned the identity hash. That inconsistency
violated the `equals`/`hashCode` contract and broke `HashMap`/`HashSet`
membership for equal-but-distinct `BasicHeader` instances. As of 10.0.0
`hashCode()` is derived from `name` + value, so tw [...]
+- **Fluent request/response header & param assertions are now null-tolerant
(behavioral change).** `FluentRequestHeaderAssertion`,
`FluentRequestQueryParamAssertion`, and `FluentRequestFormParamAssertion`
(`juneau-rest-server`) and `FluentResponseHeaderAssertion`
(`juneau-rest-client-classic`) previously threw a `NullPointerException` when
constructed against a `null` header/part (e.g. asserting on a header that was
never sent). As of 10.0.0 a `null` value is tolerated: the assertion is [...]
+
- **HTTP request/response/entity/part getters in `juneau-rest-common`,
`juneau-rest-common-classic`, and `juneau-rest-client-classic` no longer expose
live internal state (behavioral change).** To prevent cross-caller/cross-thread
state corruption (several of the affected objects are shared singletons — e.g.
the `Ok.OK` response and the ~33/~22 pre-built exception/response `INSTANCE`s),
the following now return defensive copies / unmodifiable views rather than the
live field:
- `byte[]` getters
(`ByteArrayEntity`/`StreamEntity`/`FileEntity`/`ReaderEntity`/`StringEntity.asBytes()`),
`HeaderElement[]` getters (`BasicHeader.getElements()`,
`ResponseHeader.getElements()`), and CSV token-array getters
(`BasicCsvHeader`/`BasicCsvArrayPart`/`HttpCsvHeader`/`HttpCsvArrayPart.orElse(...)`)
now return a `clone()`/copy. Mutating a returned array no longer affects the
source object or any shared constant.
- The cached remote-interface metadata
(`RrpcInterfaceMeta`/`RrpcInterfaceMethodMeta`/`Policy`, and `RemoteMeta`'s
header list) now hands out copies/unmodifiable views instead of the live cached
array/list.