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 42c53f8b38 docs(9.5): document TODO-21 Bean→Marshalled rename,
MarshalledAs, @Bean inject annotation
42c53f8b38 is described below
commit 42c53f8b381f525cab1a9256bb88a10f7e09dba2
Author: James Bognar <[email protected]>
AuthorDate: Mon May 11 17:59:01 2026 -0400
docs(9.5): document TODO-21 Bean→Marshalled rename, MarshalledAs, @Bean
inject annotation
- Release notes: new juneau-marshall section covering all annotation and
engine type renames,
MarshalledAs enum, @Marshalled(as=STRING), updated @MarshalledIgnore TYPE
semantics,
and @RestInject→@Bean (juneau-rest-server) entry
- Migration guide: new Bean→Marshalled section with Old→New tables for all
5 annotation
renames (incl. @MarshalledIgnore TYPE semantic change), 10 engine type
renames, and
@RestInject→@Bean package change with import; updated pre-existing rows
from @RestInject→@Bean
- Topic pages: updated titles and content in BeanAnnotation.md
(@Marshalled), BeanpAnnotation.md
(@MarshalledProp), BeancAnnotation.md (@MarshalledCtor),
BeanIgnoreAnnotation.md
(@MarshalledIgnore with migration note), BeanContextBasics.md
(MarshallingContext),
JavaMethodParameters.md (MarshallingContext + @Bean inject link)
Co-authored-by: Cursor <[email protected]>
---
pages/release-notes/9.5.0.md | 125 +++++++++++++++++++++++---
pages/topics/02.04.01.BeanContextBasics.md | 16 ++--
pages/topics/02.04.03.BeanAnnotation.md | 70 +++++++++------
pages/topics/02.04.04.BeanpAnnotation.md | 66 +++++++-------
pages/topics/02.04.05.BeancAnnotation.md | 24 ++---
pages/topics/02.04.06.BeanIgnoreAnnotation.md | 52 +++++++----
pages/topics/10.04.03.JavaMethodParameters.md | 4 +-
pages/topics/23.01.V9.5-migration-guide.md | 74 ++++++++++++---
8 files changed, 308 insertions(+), 123 deletions(-)
diff --git a/pages/release-notes/9.5.0.md b/pages/release-notes/9.5.0.md
index a8b76af9fa..f6022db9a0 100644
--- a/pages/release-notes/9.5.0.md
+++ b/pages/release-notes/9.5.0.md
@@ -10,6 +10,84 @@ Juneau 9.5.0 is a minor release with native TOML and YAML
support, BSON (Binary
### juneau-marshall
+#### Bean→Marshalled Rename (TODO-21)
+
+A comprehensive rename of annotation and engine types to clarify the
distinction between *Java-bean-structure* types (which keep `BeanXxx` names)
and *marshalling-process* types (which are now `MarshallingXxx`).
+
+##### Annotation Renames (breaking)
+
+| Old | New |
+|-----|-----|
+| `@Bean` (marshall) | `@Marshalled` |
+| `@BeanApply` | `@MarshalledApply` |
+| `@Beanp` | `@MarshalledProp` |
+| `@BeanpApply` | `@MarshalledPropApply` |
+| `@Beanc` | `@MarshalledCtor` |
+| `@BeancApply` | `@MarshalledCtorApply` |
+| `@BeanIgnore` | `@MarshalledIgnore` |
+| `@BeanIgnoreApply` | `@MarshalledIgnoreApply` |
+| `@BeanConfig` | `@MarshalledConfig` |
+
+##### Engine Type Renames (breaking)
+
+| Old | New |
+|-----|-----|
+| `BeanContext` | `MarshallingContext` |
+| `BeanContextable` | `MarshallingContextable` |
+| `BeanSession` | `MarshallingSession` |
+| `BeanTraverseContext` | `MarshallingTraverseContext` |
+| `BeanTraverseSession` | `MarshallingTraverseSession` |
+| `BeanRecursionException` | `MarshallingRecursionException` |
+| `BeanInterceptor` | `MarshallingInterceptor` |
+| `BeanStringSwap` | `MarshallingStringSwap` |
+| `BeanContextConverter` | `MarshallingContextConverter` |
+| `BeanDefMapper` | `MarshallingDefMapper` |
+| `BeanContext.DEFAULT` | `MarshallingContext.DEFAULT` |
+
+##### Unchanged Types (clarification)
+
+The following `BeanXxx` types model the *Java bean structure* and are
deliberately unchanged:
+`BeanMap`, `BeanMeta`, `BeanPropertyMeta`, `BeanPropertyValue`,
`BeanPropertyConsumer`, `BeanRegistry`, `BeanDictionaryMap`,
`BeanDictionaryList`, `BeanProxyInvocationHandler`, `BeanDiff`.
+
+##### New Feature: `@Marshalled(as=STRING)` Strategy
+
+A new `MarshalledAs` enum with values `DETECT` (default) and `STRING` has been
added to `@Marshalled`:
+
+```java
+// Force a type to serialize as its toString() value, bypassing bean detection.
+@Marshalled(as=STRING)
+public class MyType {
+ @Override public String toString() { return "my-string-form"; }
+}
+```
+
+`@Marshalled(as=STRING)` replaces two earlier patterns:
+- The `BeanStringSwap` class (now `MarshallingStringSwap`; kept for custom
format overrides)
+- The `@BeanIgnore`-on-class-then-`toString()` pattern
+
+##### Updated `@MarshalledIgnore` TYPE Semantics (breaking)
+
+Applying `@MarshalledIgnore` to a **class** now skips serialization entirely
(outputs `null`) instead of falling through to `toString()`:
+
+```java
+// Before (@BeanIgnore on class → toString())
+@BeanIgnore
+public class OldClass { @Override public String toString() { return "value"; }
}
+// Serialized as: "value"
+
+// After (@MarshalledIgnore on class → null)
+@MarshalledIgnore
+public class NewClass { ... }
+// Serialized as: null
+
+// Migration: if you need toString() behavior, use @Marshalled(as=STRING)
instead
+@Marshalled(as=STRING)
+public class NewClass { @Override public String toString() { return "value"; }
}
+// Serialized as: "value"
+```
+
+**Migration:** If you previously used `@BeanIgnore` on a class to force
`toString()` serialization, replace it with `@Marshalled(as=STRING)`. If you
truly want to suppress serialization (output `null`), use `@MarshalledIgnore`.
+
#### `@Beanp("*")` on non-Map fields
On a field whose type is not a `Map`, `@Beanp("*")` (or `@Beanp(name="*")`) no
longer tries to register a dyna property. The property name is taken from the
field (via the configured `PropertyNamer`); other `@Beanp` attributes still
apply. `Map` fields keep the dyna property `*` as before.
@@ -976,7 +1054,7 @@ Final resolve order on `BasicBeanStore` is:
```text
overridingParent.getBeanSupplier(type, name) // outer scope (e.g.
Spring)
- -> entries[type][name] // addBean(...) /
@RestInject
+ -> entries[type][name] // addBean(...) / @Bean
-> parent.getBeanSupplier(type, name) // regular fallback
-> defaults[type][name] // addDefaultSupplier(...)
```
@@ -1161,6 +1239,25 @@ String name
### juneau-rest-server
+#### `@RestInject` Renamed to `@Bean` (moved to `juneau-commons`)
+
+`@RestInject` has been renamed to `@Bean` and moved from
`org.apache.juneau.rest.annotation` to
+`org.apache.juneau.commons.inject`. Update imports accordingly:
+
+```java
+// Before
+import org.apache.juneau.rest.annotation.RestInject;
+@RestInject
+public EncoderSet myEncoders(BeanStore bs) { ... }
+
+// After
+import org.apache.juneau.commons.inject.Bean;
+@Bean
+public EncoderSet myEncoders(BeanStore bs) { ... }
+```
+
+The semantics are identical; only the package and annotation name changed.
+
#### `SpringBeanStore2` Renamed to `SpringBeanStore`
`SpringBeanStore2` has been renamed to `SpringBeanStore` for consistency with
the `BasicBeanStore2` → `BasicBeanStore` rename completed in this release. The
old name `SpringBeanStore2` is removed; update any import or type reference to
`org.apache.juneau.rest.springboot.SpringBeanStore`.
@@ -1272,29 +1369,29 @@ Generated Swagger (OpenAPI 2) for REST operations now
includes optional document
#### `RestContext.Builder` and `RestOpContext.Builder` removed
-`RestContext.Builder` and `RestOpContext.Builder` are no longer part of the
public API. All resource-level and operation-level configuration that was
previously expressed through fluent builder calls now flows exclusively through
`@Rest(...)` / `@RestOp(...)` annotation attributes or `@RestInject`-annotated
methods and fields.
+`RestContext.Builder` and `RestOpContext.Builder` are no longer part of the
public API. All resource-level and operation-level configuration that was
previously expressed through fluent builder calls now flows exclusively through
`@Rest(...)` / `@RestOp(...)` annotation attributes or `@Bean`-annotated
methods and fields.
Key changes:
-- **`RestContext.Builder`** — entirely removed from public surface; the
framework no longer publishes a builder instance to `@RestInit` hooks or the
resource constructor. Replace each `builder.xxx(...)` call with the equivalent
`@Rest(xxx=...)` attribute or an `@RestInject(name="xxx")`-annotated
bean-supplier method.
+- **`RestContext.Builder`** — entirely removed from public surface; the
framework no longer publishes a builder instance to `@RestInit` hooks or the
resource constructor. Replace each `builder.xxx(...)` call with the equivalent
`@Rest(xxx=...)` attribute or a `@Bean(name="xxx")`-annotated bean-supplier
method.
- **`RestOpContext.Builder`** — same removal. Replace `builder.guards(...)`,
`builder.converters(...)`, etc. with `@RestOp(guards=...)`,
`@RestOp(converters=...)`, etc.
- **`RestContextInit` record** replaces the old
`RestContext.create(resourceClass, parent,
cfg).init(supplier).path(p).children(c).build()` factory chain. The six
bootstrap fields (resource class, parent context, servlet config, resource
supplier, path, children) plus an optional `Consumer<BasicBeanStore>` hook are
bundled in one immutable record. The common top-level case becomes `new
RestContext(new RestContextInit(MyResource.class, () -> new MyResource()))`.
-- **`@RestInit(RestContext.Builder b)`** / **`@RestInit(RestOpContext.Builder
b)`** injection hooks — removed. The supported `@RestInit` parameter shapes are
now `ServletConfig`, `ServletContext`, the resource instance,
`@RestInject`-supplied beans, and zero-arg.
-- **Annotation memoizers** — every setting previously set by the builder is
now computed lazily by a `findXxx()` method on `RestContext` / `RestOpContext`
that walks the `@Rest` / `@RestOp` annotation chain, system properties, and the
`@RestInject` bean store. Results are cached in a `Memoizer<T>` and invalidated
by `RestContext.reset()`.
+- **`@RestInit(RestContext.Builder b)`** / **`@RestInit(RestOpContext.Builder
b)`** injection hooks — removed. The supported `@RestInit` parameter shapes are
now `ServletConfig`, `ServletContext`, the resource instance, `@Bean`-supplied
beans, and zero-arg.
+- **Annotation memoizers** — every setting previously set by the builder is
now computed lazily by a `findXxx()` method on `RestContext` / `RestOpContext`
that walks the `@Rest` / `@RestOp` annotation chain, system properties, and the
`@Bean` bean store. Results are cached in a `Memoizer<T>` and invalidated by
`RestContext.reset()`.
See the [V9.5 Migration Guide](/docs/topics/V9.5-migration-guide) for a
per-setting replacement table.
-#### Bean precedence: Spring > `@RestInject` > default (breaking)
+#### Bean precedence: Spring > `@Bean` (inject) > default (breaking)
The precedence order used by `RestContext` to resolve framework-managed beans
(`CallLogger`, `EncoderSet`, `SerializerSet`, `ParserSet`, `ThrownStore`,
`Config`, `VarResolver`, `HttpPartSerializer`, `HttpPartParser`, `Messages`,
`MethodExecStore`, `JsonSchemaGenerator`, `StaticFiles`, `DebugEnablement`,
`SwaggerProvider`, `RestOperations`, `RestChildren`, named `HeaderList` /
`NamedAttributeMap` slots, etc.) has been flipped:
| Tier | 9.4 and earlier | 9.5+ |
| ---- | --------------- | ---- |
-| 1 (highest) | `@RestInject` method on the resource | **Spring `@Bean`** (or
any bean reachable through the bootstrap / overriding-parent bean store) |
-| 2 | Spring `@Bean` (via `SpringBeanStore`) | **`@RestInject` method on the
resource** |
+| 1 (highest) | `@Bean` (inject) method on the resource | **Spring `@Bean`**
(or any bean reachable through the bootstrap / overriding-parent bean store) |
+| 2 | Spring `@Bean` (via `SpringBeanStore`) | **`@Bean` (inject) method on
the resource** |
| 3 (lowest) | Memoizer-backed framework default | **Memoizer-backed framework
default** |
-`@RestInject` is now documented as a *programmable default*, analogous to
Spring's `@ConditionalOnMissingBean`: if a Spring bean of the same type (and
name, where named) is available, it wins; otherwise the `@RestInject` method
runs and its result is cached. Resolution short-circuits on the first hit, so
non-Spring deployments collapse to the familiar `@RestInject > default` chain.
+`@Bean` (inject) is now documented as a *programmable default*, analogous to
Spring's `@ConditionalOnMissingBean`: if a Spring bean of the same type (and
name, where named) is available, it wins; otherwise the `@Bean` method runs and
its result is cached. Resolution short-circuits on the first hit, so non-Spring
deployments collapse to the familiar `@Bean > default` chain.
Mechanically, the change is implemented through three new affordances on
`BasicBeanStore`:
@@ -1304,18 +1401,18 @@ Mechanically, the change is implemented through three
new affordances on `BasicB
Side effects of the new model:
-- The legacy `DELAYED_INJECTION` / `DELAYED_INJECTION_NAMES` skip lists in
`RestContext` are gone. The `@RestInject` method walk now runs for every type
with no hand-maintained filter; default-supplier presence is what auto-derives
"skip this for now" behavior.
+- The legacy `DELAYED_INJECTION` / `DELAYED_INJECTION_NAMES` skip lists in
`RestContext` are gone. The `@Bean` (inject) method walk now runs for every
type with no hand-maintained filter; default-supplier presence is what
auto-derives "skip this for now" behavior.
- Inside each framework-bean memoizer body, redundant
`bs.getBean(X).ifPresent(impl::override)` lookups have been removed. The bean
store is the precedence engine — defaults no longer probe the store on the way
out.
- All `RestContext.getX()` accessor methods (`getCallLogger()`, `getConfig()`,
`getVarResolver()`, etc.) now route through `beanStore.getBean(X)`, so internal
callers see Spring overrides without needing to hit the bean store directly.
##### Migration
-If you previously relied on `@RestInject` overriding a Spring `@Bean`, you
have a few options in 9.5+:
+If you previously relied on `@Bean` (inject) overriding a Spring `@Bean`, you
have a few options in 9.5+:
-- **Preferred — let Spring win.** Remove the `@RestInject` method and lean on
the Spring bean. The `@RestInject` was effectively a "default", which Spring
already provides via `@ConditionalOnMissingBean` semantics on the bean factory.
-- **Skip the Spring `@Bean`.** Don't declare the type as a Spring `@Bean` and
the `@RestInject` method will continue to win over the framework default.
+- **Preferred — let Spring win.** Remove the `@Bean` (inject) method and lean
on the Spring bean. The `@Bean` (inject) method was effectively a "default",
which Spring already provides via `@ConditionalOnMissingBean` semantics on the
bean factory.
+- **Skip the Spring `@Bean`.** Don't declare the type as a Spring `@Bean` and
the `@Bean` (inject) method will continue to win over the framework default.
- **Use Spring-native overrides.** Mark the relevant Spring bean with
`@Primary`, `@MockBean`, or `@ConditionalOnProperty` so Spring itself picks the
right candidate. The bean store will then surface that candidate to
`RestContext`.
-- **Programmatic registrations** that flow through
`args.beanStoreConfigurer()` (the `Consumer<BasicBeanStore>` hook on
`RestContextInit`) land as *regular* entries — the same tier as `@RestInject`.
They no longer beat Spring; if you need that, register the bean as a Spring
`@Bean` (or contribute it through the overriding-parent layer in a custom
`BasicBeanStore` subclass).
+- **Programmatic registrations** that flow through
`args.beanStoreConfigurer()` (the `Consumer<BasicBeanStore>` hook on
`RestContextInit`) land as *regular* entries — the same tier as `@Bean`
(inject). They no longer beat Spring; if you need that, register the bean as a
Spring `@Bean` (or contribute it through the overriding-parent layer in a
custom `BasicBeanStore` subclass).
`SpringBeanStore` keeps backward-compatible behavior at the API level: as a
`BasicBeanStore` subclass it picks up the new precedence model automatically
when used through `RestContext`. Custom `BasicBeanStore` subclasses that want
Spring-equivalent precedence can wire themselves in via
`Builder.overridingParent(...)`; the existing `parent(...)` slot continues to
behave as a regular fallback (consulted after local entries).
diff --git a/pages/topics/02.04.01.BeanContextBasics.md
b/pages/topics/02.04.01.BeanContextBasics.md
index aa81c68b65..bf3d766cb1 100644
--- a/pages/topics/02.04.01.BeanContextBasics.md
+++ b/pages/topics/02.04.01.BeanContextBasics.md
@@ -1,32 +1,32 @@
---
-title: "Bean Context Basics"
+title: "Marshalling Context Basics"
slug: BeanContextBasics
---
-At the heart of the marshalling APIs is the <a
href="/site/apidocs/org/apache/juneau/BeanContext.html" target="_blank">Bean
Context</a> API that
+At the heart of the marshalling APIs is the <a
href="/site/apidocs/org/apache/juneau/MarshallingContext.html"
target="_blank">Marshalling Context</a> API that
provides a common framework for marshalling beans and POJOs across all
serializers and parsers.
-All serializers and parsers (and their builders) extend from the bean context
API classes.
+All serializers and parsers (and their builders) extend from the marshalling
context API classes.
-One important feature of the bean context API is the ability to wrap Java
beans inside maps to allow properties to be
+One important feature of the marshalling context API is the ability to wrap
Java beans inside maps to allow properties to be
accessed through a Map layer.
Although this is used internally by all the serializers and parsers, it's
often useful to use this feature by itself.
:::tip Example
```java
// Wrap a bean in a map and do some simple get/set calls.
-BeanMap myBeanMap = BeanContext.DEFAULT_SESSION.toBeanMap(myBean);
+BeanMap myBeanMap = MarshallingContext.DEFAULT_SESSION.toBeanMap(myBean);
myBeanMap.put("myProperty", 123);
int myProperty = myBeanMap.get("myProperty", int.class);
```
:::
-The bean context API provides many settings that fine-tune how POJOs should be
handled during marshalling.
+The marshalling context API provides many settings that fine-tune how POJOs
should be handled during marshalling.
:::info See Also
<tree>
-<node-0><java-class><a
href="/site/apidocs/org/apache/juneau/BeanContext.Builder.html"
target="_blank">BeanContext.Builder</a></java-class></node-0>
+<node-0><java-class><a
href="/site/apidocs/org/apache/juneau/MarshallingContext.Builder.html"
target="_blank">MarshallingContext.Builder</a></java-class></node-0>
</tree>
-:::
\ No newline at end of file
+:::
diff --git a/pages/topics/02.04.03.BeanAnnotation.md
b/pages/topics/02.04.03.BeanAnnotation.md
index 623ff35f03..39d0a7a795 100644
--- a/pages/topics/02.04.03.BeanAnnotation.md
+++ b/pages/topics/02.04.03.BeanAnnotation.md
@@ -1,38 +1,38 @@
---
-title: "@Bean Annotation"
+title: "@Marshalled Annotation"
slug: BeanAnnotation
---
-The <a href="/site/apidocs/org/apache/juneau/annotation/Bean.html"
target="_blank">@Bean</a> annotation is used to tailor how beans are interpreted
+The <a href="/site/apidocs/org/apache/juneau/annotation/Marshalled.html"
target="_blank">@Marshalled</a> annotation is used to tailor how beans and
types are interpreted
by the framework.
-Bean property inclusion and ordering on a bean class can be done using the <a
href="/site/apidocs/org/apache/juneau/annotation/Bean.html#properties()"
target="_blank">@Bean(properties|p)</a> annotation.
+Bean property inclusion and ordering on a bean class can be done using the <a
href="/site/apidocs/org/apache/juneau/annotation/Marshalled.html#properties()"
target="_blank">@Marshalled(properties|p)</a> annotation.
```java
// Address class with only street/city/state properties (in that order).
// All other properties are ignored.
-@Bean(properties="street,city,state")
+@Marshalled(properties="street,city,state")
public class Address { ... }
```
-Bean properties can be excluded using the <a
href="/site/apidocs/org/apache/juneau/annotation/Bean.html#excludeProperties()"
target="_blank">@Bean(excludeProperties|xp)</a> annotation.
+Bean properties can be excluded using the <a
href="/site/apidocs/org/apache/juneau/annotation/Marshalled.html#excludeProperties()"
target="_blank">@Marshalled(excludeProperties|xp)</a> annotation.
```java
// Address class with only street/city/state properties (in that order).
// All other properties are ignored.
-@Bean(excludeProperties="city,state"})
+@Marshalled(excludeProperties="city,state"})
public class Address { ... }
```
-Bean properties are sorted alphabetically by default. To opt a specific bean
out of this default sorting, use <a
href="/site/apidocs/org/apache/juneau/annotation/Bean.html#unsorted()"
target="_blank">@Bean(unsorted)</a>:
+Bean properties are sorted alphabetically by default. To opt a specific bean
out of this default sorting, use <a
href="/site/apidocs/org/apache/juneau/annotation/Marshalled.html#unsorted()"
target="_blank">@Marshalled(unsorted)</a>:
```java
// Opt this bean out of the default alphabetical property ordering.
-@Bean(unsorted=true)
+@Marshalled(unsorted=true)
public class MyBean { ... }
```
-Sorting can also be disabled globally for all beans via
`BeanContext.Builder.unsortedProperties()`:
+Sorting can also be disabled globally for all beans via
`MarshallingContext.Builder.unsortedProperties()`:
```java
WriterSerializer serializer = JsonSerializer
@@ -50,7 +50,7 @@ WriterSerializer serializer = JsonSerializer
.build();
```
-The <a
href="/site/apidocs/org/apache/juneau/annotation/Bean.html#propertyNamer()"
target="_blank">@Bean(propertyNamer)</a> annotation is used to
+The <a
href="/site/apidocs/org/apache/juneau/annotation/Marshalled.html#propertyNamer()"
target="_blank">@Marshalled(propertyNamer)</a> annotation is used to
provide customized naming of properties.
Property namers are used to transform bean property names from standard form
to some other form.
@@ -59,18 +59,18 @@ dashed-lowercase, and these will be used as attribute names
in JSON and element
```java
// Define a class with dashed-lowercase property names.
-@Bean(propertyNamer=PropertyNamerDashedLC.class)
+@Marshalled(propertyNamer=PropertyNamerDashedLC.class)
public class MyBean { ... }
```
-The <a
href="/site/apidocs/org/apache/juneau/annotation/Bean.html#interfaceClass()"
target="_blank">@Bean(interfaceClass)</a> annotation is used to
+The <a
href="/site/apidocs/org/apache/juneau/annotation/Marshalled.html#interfaceClass()"
target="_blank">@Marshalled(interfaceClass)</a> annotation is used to
limit properties on beans to specific interface classes.
When specified, only the list of properties defined on the interface class
will be used during serialization.
Additional properties on subclasses will be ignored.
```java
// Parent class
-@Bean(interfaceClass=A.class)
+@Marshalled(interfaceClass=A.class)
public abstract class A {
public String f0 = "f0";
}
@@ -88,7 +88,7 @@ assertEquals("{f0:'f0'}", result); // Note f1 is not
serialized.
Note that this annotation can be used on the parent class so that it filters
to all child classes.
Or can be set individually on the child classes.
-The <a href="/site/apidocs/org/apache/juneau/annotation/Bean.html#stopClass()"
target="_blank">@Bean(stopClass)</a> annotation is another way to limit
+The <a
href="/site/apidocs/org/apache/juneau/annotation/Marshalled.html#stopClass()"
target="_blank">@Marshalled(stopClass)</a> annotation is another way to limit
which properties are serialized (except from the opposite direction).
It's identical in purpose to the stop class specified by
[Introspector.getBeanInfo(Class,Class)](https://docs.oracle.com/javase/17/docs/api/java.desktop/java/beans/Introspector.html#getBeanInfo(java.lang.Class,java.lang.Class)).
Any properties in the stop class or in its base classes will be ignored during
analysis.
@@ -104,17 +104,17 @@ public class C2 extends C1 {
public int getP2();
}
-@Bean(stopClass=C2.class)
+@Marshalled(stopClass=C2.class)
public class C3 extends C2 {
public int getP3();
}
```
-The <a
href="/site/apidocs/org/apache/juneau/annotation/Bean.html#interceptor()"
target="_blank">@Bean(interceptor)</a> annotation and <a
href="/site/apidocs/org/apache/juneau/swap/BeanInterceptor.html"
target="_blank">BeanInterceptor</a> class can be used to perform interception
and inline handling of bean getter and setter calls.
+The <a
href="/site/apidocs/org/apache/juneau/annotation/Marshalled.html#interceptor()"
target="_blank">@Marshalled(interceptor)</a> annotation and <a
href="/site/apidocs/org/apache/juneau/swap/MarshallingInterceptor.html"
target="_blank">MarshallingInterceptor</a> class can be used to perform
interception and inline handling of bean getter and setter calls.
```java
// Interceptor that strips out sensitive information on Address beans.
-public class AddressInterceptor extends BeanInterceptor {
+public class AddressInterceptor extends MarshallingInterceptor {
@Override
public Object readProperty(Address bean, String name, Object value) {
@@ -132,17 +132,17 @@ public class AddressInterceptor extends BeanInterceptor {
}
// Register interceptor on bean class.
-@Bean(interceptor=AddressInterceptor.class)
+@Marshalled(interceptor=AddressInterceptor.class)
public class Address {
public String getTaxInfo() {...}
public void setTaxInfo(String value) {...}
}
```
-The <a href="/site/apidocs/org/apache/juneau/annotation/Bean.html#on()"
target="_blank">@Bean(on)</a> and <a
href="/site/apidocs/org/apache/juneau/annotation/Bean.html#onClass()"
target="_blank">@Bean(onClass)</a> annotations can be used to programmatically
attach @Bean annotations to classes.
+The <a href="/site/apidocs/org/apache/juneau/annotation/Marshalled.html#on()"
target="_blank">@Marshalled(on)</a> and <a
href="/site/apidocs/org/apache/juneau/annotation/Marshalled.html#onClass()"
target="_blank">@Marshalled(onClass)</a> annotations can be used to
programmatically attach `@Marshalled` annotations to classes.
```java
-@Bean(onClass=Address.class, unsorted=true, excludeProperties="city,state")
+@Marshalled(onClass=Address.class, unsorted=true,
excludeProperties="city,state")
public class MyAnnotatedClass {...}
// Create a serializer configured using annotations.
@@ -152,18 +152,38 @@ JsonSerializer serializer = JsonSerializer
.build();
```
+## `as` Strategy: Serialize as String
+
+The `as` attribute controls how the type is serialized at a high level. The <a
href="/site/apidocs/org/apache/juneau/annotation/MarshalledAs.html"
target="_blank">MarshalledAs</a> enum has two values:
+
+- **`DETECT`** (default) — normal bean detection and serialization.
+- **`STRING`** — forces the type to serialize via `toString()`, regardless of
its bean structure.
+
+```java
+// Always serialize as the toString() value, not as a bean.
+@Marshalled(as=MarshalledAs.STRING)
+public class MyId {
+ private final long id;
+ public MyId(long id) { this.id = id; }
+ @Override public String toString() { return String.valueOf(id); }
+}
+```
+
+`@Marshalled(as=STRING)` replaces both the `MarshallingStringSwap` class
approach and the former
+`@MarshalledIgnore`-on-class-then-`toString()` pattern. See the V9.5 migration
guide for details.
+
## Java Records
-When using `@Bean` with Java records, note the following:
+When using `@Marshalled` with Java records, note the following:
-- **`@Bean(properties)`** can be used to control property order, but all
record components should be included.
+- **`@Marshalled(properties)`** can be used to control property order, but all
record components should be included.
Omitting components will prevent parsing since all components must be
provided to the canonical constructor.
-- **`@Bean(excludeProperties)`** will exclude components from serialization
output, but excluded components will
+- **`@Marshalled(excludeProperties)`** will exclude components from
serialization output, but excluded components will
cause parsing to fail if their values are missing from the input.
-- **`@Bean(readOnlyProperties)`** will cause parsing to fail for the same
reason.
+- **`@Marshalled(readOnlyProperties)`** will cause parsing to fail for the
same reason.
If you need to omit components during parsing, use
-<a href="/site/apidocs/org/apache/juneau/annotation/Beanc.html"
target="_blank">@Beanc</a> with a non-canonical
+<a href="/site/apidocs/org/apache/juneau/annotation/MarshalledCtor.html"
target="_blank">@MarshalledCtor</a> with a non-canonical
constructor that provides defaults for the omitted components.
:::info See Also
diff --git a/pages/topics/02.04.04.BeanpAnnotation.md
b/pages/topics/02.04.04.BeanpAnnotation.md
index 79b045e92e..b342896822 100644
--- a/pages/topics/02.04.04.BeanpAnnotation.md
+++ b/pages/topics/02.04.04.BeanpAnnotation.md
@@ -1,17 +1,17 @@
---
-title: "@Beanp Annotation"
+title: "@MarshalledProp Annotation"
slug: BeanpAnnotation
---
-The <a href="/site/apidocs/org/apache/juneau/annotation/Beanp.html"
target="_blank">@Beanp</a> annotation is used to tailor how individual bean
+The <a href="/site/apidocs/org/apache/juneau/annotation/MarshalledProp.html"
target="_blank">@MarshalledProp</a> annotation is used to tailor how individual
bean
properties are interpreted by the framework.
-The <a href="/site/apidocs/org/apache/juneau/annotation/Beanp.html#name()"
target="_blank">@Beanp(name)</a> annotation is used to override the name
+The <a
href="/site/apidocs/org/apache/juneau/annotation/MarshalledProp.html#name()"
target="_blank">@MarshalledProp(name)</a> annotation is used to override the
name
of the bean property.
```java
public class MyBean {
- @Beanp(name="Bar")
+ @MarshalledProp(name="Bar")
public String getFoo() {...}
}
```
@@ -26,14 +26,14 @@ public class MyBean {
}
```
-If the <a
href="/site/apidocs/org/apache/juneau/BeanContext.Builder.html#beanFieldVisibility(org.apache.juneau.Visibility)"
target="_blank">beanFieldVisibility</a>
-setting on the bean context excludes this field (e.g.
+If the <a
href="/site/apidocs/org/apache/juneau/MarshallingContext.Builder.html#beanFieldVisibility(org.apache.juneau.Visibility)"
target="_blank">beanFieldVisibility</a>
+setting on the marshalling context excludes this field (e.g.
the visibility is set to the default of PUBLIC but the field is PROTECTED),
this annotation can be used to force the
field to be identified as a property.
```java
public class MyBean {
- @Beanp
+ @MarshalledProp
protected String getFoo() {...}
}
```
@@ -51,7 +51,7 @@ The following shows various ways of using dynamic bean
properties.
// The field name can be anything.
public class BeanWithDynaField {
- @Beanp("*")
+ @MarshalledProp("*")
public Map extraStuff = new LinkedHashMap();
}
@@ -61,12 +61,12 @@ public class BeanWithDynaField {
// Setter must take in two arguments, a String and Object.
public class BeanWithDynaMethods {
- @Beanp("*")
+ @MarshalledProp("*")
public Map getMyExtraStuff() {
...
}
- @Beanp("*")
+ @MarshalledProp("*")
public void setAnExtraField(String name, Object value) {
...
}
@@ -76,7 +76,7 @@ public class BeanWithDynaMethods {
// Properties will be added through the getter.
public class BeanWithDynaGetterOnly {
- @Beanp("*")
+ @MarshalledProp("*")
public Map getMyExtraStuff() {
...
}
@@ -90,7 +90,7 @@ The property values optionally can be any serializable type
or use swaps.
// A serializable type other than Object.
public class BeanWithDynaFieldWithListValues {
- @Beanp("*")
+ @MarshalledProp("*")
public Map> getMyExtraStuff() {
...
}
@@ -99,7 +99,7 @@ public class BeanWithDynaFieldWithListValues {
// A swapped value.
public class BeanWithDynaFieldWithSwappedValues {
- @Beanp(name="*", swap=TemporalCalendarSwap.IsoOffsetDateTime.class)
+ @MarshalledProp(name="*",
swap=TemporalCalendarSwap.IsoOffsetDateTime.class)
public Map getMyExtraStuff() {
...
}
@@ -107,21 +107,21 @@ public class BeanWithDynaFieldWithSwappedValues {
```
:::note
-Note that if you're not interested in these additional properties, you can
also use the <a
href="/site/apidocs/org/apache/juneau/BeanContext.Builder.html#ignoreUnknownBeanProperties()"
target="_blank">ignoreUnknownBeanProperties</a> setting to ignore values that
don't fit into existing properties.
+Note that if you're not interested in these additional properties, you can
also use the <a
href="/site/apidocs/org/apache/juneau/MarshallingContext.Builder.html#ignoreUnknownBeanProperties()"
target="_blank">ignoreUnknownBeanProperties</a> setting to ignore values that
don't fit into existing properties.
:::
-The <a href="/site/apidocs/org/apache/juneau/annotation/Beanp.html#value()"
target="_blank">@Beanp(value)</a> annotation is a synonym for <a
href="/site/apidocs/org/apache/juneau/annotation/Beanp.html#name()"
target="_blank">@Beanp(name)</a>.
+The <a
href="/site/apidocs/org/apache/juneau/annotation/MarshalledProp.html#value()"
target="_blank">@MarshalledProp(value)</a> annotation is a synonym for <a
href="/site/apidocs/org/apache/juneau/annotation/MarshalledProp.html#name()"
target="_blank">@MarshalledProp(name)</a>.
Use it in cases where you're only specifying a name so that you can shorten
your annotation.
The following annotations are equivalent:
```java
-@Beanp(name="foo")
+@MarshalledProp(name="foo")
-@Beanp("foo")
+@MarshalledProp("foo")
```
-The <a href="/site/apidocs/org/apache/juneau/annotation/Beanp.html#type()"
target="_blank">@Beanp(type)</a> annotation is used to identify a
+The <a
href="/site/apidocs/org/apache/juneau/annotation/MarshalledProp.html#type()"
target="_blank">@MarshalledProp(type)</a> annotation is used to identify a
specialized class type for a generalized property.
Normally the type is inferred through reflection of the field type or getter
return type.
However, you'll want to specify this value if you're parsing beans where the
bean property class is an interface or
@@ -135,12 +135,12 @@ This property must denote a concrete class with a no-arg
constructor.
public class MyBean {
// Identify concrete type as a HashMap.
- @Beanp(type=HashMap.class)
+ @MarshalledProp(type=HashMap.class)
public Map p1;
}
```
-The <a href="/site/apidocs/org/apache/juneau/annotation/Beanp.html#params()"
target="_blank">@Beanp(params)</a> annotation is for bean properties of
+The <a
href="/site/apidocs/org/apache/juneau/annotation/MarshalledProp.html#params()"
target="_blank">@MarshalledProp(params)</a> annotation is for bean properties of
type map or collection.
It's used to identify the class types of the contents of the bean property
object when the general parameter types are
interfaces or abstract classes.
@@ -149,12 +149,12 @@ interfaces or abstract classes.
public class MyBean {
// This is a HashMap.
- @Beanp(type=HashMap.class, params={String.class,Integer.class})
+ @MarshalledProp(type=HashMap.class, params={String.class,Integer.class})
public Map p1;
}
```
-The <a
href="/site/apidocs/org/apache/juneau/annotation/Beanp.html#properties()"
target="_blank">@Beanp(properties)</a> annotation is used to limit
+The <a
href="/site/apidocs/org/apache/juneau/annotation/MarshalledProp.html#properties()"
target="_blank">@MarshalledProp(properties)</a> annotation is used to limit
which child properties are rendered by the serializers.
It can be used on any of the following bean property types:
@@ -167,7 +167,7 @@ It can be used on any of the following bean property types:
```java
public class MyClass {
// Only render 'f1' when serializing this bean property.
- @Beanp(properties={"f1"})
+ @MarshalledProp(properties={"f1"})
public MyChildClass x1 = new MyChildClass();
}
@@ -180,22 +180,22 @@ public class MyChildClass {
String json = Json.of(new MyClass());
```
-The <a href="/site/apidocs/org/apache/juneau/annotation/Beanp.html#format()"
target="_blank">@Beanp(format)</a> annotation specifies a String format
+The <a
href="/site/apidocs/org/apache/juneau/annotation/MarshalledProp.html#format()"
target="_blank">@MarshalledProp(format)</a> annotation specifies a String format
for converting a bean property value to a formatted string.
```java
// Serialize a float as a string with 2 decimal places.
-@Beanp(format="$%.2f")
+@MarshalledProp(format="$%.2f")
public float price;
```
## Annotation Inheritance
:::info Since 9.2.0
-Starting with Juneau 9.2.0, `@Beanp` and `@Name` annotations are automatically
inherited when bean property methods (getters, setters, extraKeys) are
overridden in subclasses.
+Starting with Juneau 9.2.0, `@MarshalledProp` and `@Name` annotations are
automatically inherited when bean property methods (getters, setters,
extraKeys) are overridden in subclasses.
:::
-This feature is particularly useful for fluent APIs where you want to override
setters to change the return type without needing to re-annotate every method
with `@Beanp`, `@Xml`, `@Json`, and other serialization annotations.
+This feature is particularly useful for fluent APIs where you want to override
setters to change the return type without needing to re-annotate every method
with `@MarshalledProp`, `@Xml`, `@Json`, and other serialization annotations.
**Example:**
@@ -204,7 +204,7 @@ This feature is particularly useful for fluent APIs where
you want to override s
public class Parent {
private List<String> children;
- @Beanp("c") // Custom property name
+ @MarshalledProp("c") // Custom property name
@Xml(format=XmlFormat.ELEMENTS)
public List<String> getChildren() {
return children;
@@ -225,7 +225,7 @@ public class Child extends Parent {
@Override
public Child setChildren(List<String> children) {
- // ✓ Automatically inherits @Beanp("c") from parent
+ // ✓ Automatically inherits @MarshalledProp("c") from parent
// ✓ Property name remains "c" (not "children")
// ✓ No re-annotation needed!
super.setChildren(children);
@@ -240,7 +240,7 @@ When the serialization framework processes the `Child`
class, it:
1. Detects that `setChildren()` overrides a parent method
2. Walks up the class hierarchy to find the parent method
-3. Inherits the `@Beanp("c")` annotation from the parent
+3. Inherits the `@MarshalledProp("c")` annotation from the parent
4. Uses the same property name ("c") for both parent and child classes
This prevents duplicate property definitions and ensures consistent
serialization behavior across inheritance hierarchies.
@@ -264,7 +264,7 @@ If you want to override a method and use a **different**
property name, simply r
```java
public class Child extends Parent {
@Override
- @Beanp("childList") // Explicit new name
+ @MarshalledProp("childList") // Explicit new name
public Child setChildren(List<String> children) {
super.setChildren(children);
return this;
@@ -272,8 +272,8 @@ public class Child extends Parent {
}
```
-In this case, the explicit `@Beanp("childList")` takes precedence over the
inherited annotation.
+In this case, the explicit `@MarshalledProp("childList")` takes precedence
over the inherited annotation.
:::note
-Annotation inheritance applies to ALL bean property annotations, including
`@Beanp`, `@Name`, `@Xml`, `@Json`, `@Schema`, and others. This ensures
complete metadata is preserved across inheritance hierarchies.
+Annotation inheritance applies to ALL bean property annotations, including
`@MarshalledProp`, `@Name`, `@Xml`, `@Json`, `@Schema`, and others. This
ensures complete metadata is preserved across inheritance hierarchies.
:::
diff --git a/pages/topics/02.04.05.BeancAnnotation.md
b/pages/topics/02.04.05.BeancAnnotation.md
index e1ac6d3539..ae60e1891c 100644
--- a/pages/topics/02.04.05.BeancAnnotation.md
+++ b/pages/topics/02.04.05.BeancAnnotation.md
@@ -1,9 +1,9 @@
---
-title: "@Beanc Annotation"
+title: "@MarshalledCtor Annotation"
slug: BeancAnnotation
---
-The <a href="/site/apidocs/org/apache/juneau/annotation/Beanc.html"
target="_blank">@Beanc</a> annotation is used to map constructor arguments to
+The <a href="/site/apidocs/org/apache/juneau/annotation/MarshalledCtor.html"
target="_blank">@MarshalledCtor</a> annotation is used to map constructor
arguments to
property names on bean with read-only properties.
Since method parameter names are lost during compilation, this annotation
essentially redefines them so that they are
@@ -17,7 +17,7 @@ public class Person {
private final String name;
private final int age;
- @Beanc(properties="name,age"})
+ @MarshalledCtor(properties="name,age"})
public Person(String name, int age) {
this.name = name;
this.age = age;
@@ -47,17 +47,17 @@ int age = person.getAge(); // 45
Beans can also be defined with a combination of read-only and read-write
properties.
The <a href="/site/apidocs/org/apache/juneau/annotation/Name.html"
target="_blank">@Name</a> annotation can also be used instead of
-`@Beanc(properties)`:
+`@MarshalledCtor(properties)`:
```java
-@Beanc
+@MarshalledCtor
public Person(@Name("name") String name, @Name("age") int age) {
this.name = name;
this.age = age;
}
```
-If neither `@Beanc(properties)` or <a
href="/site/apidocs/org/apache/juneau/annotation/Name.html"
target="_blank">@Name</a> is used to identify the
+If neither `@MarshalledCtor(properties)` or <a
href="/site/apidocs/org/apache/juneau/annotation/Name.html"
target="_blank">@Name</a> is used to identify the
bean property names, we will try to use the parameter names if they are
available in the bytecode.
## Java Records
@@ -67,17 +67,17 @@ is not required. It can still be used to specify a
non-canonical constructor if
default values for certain components:
```java
-@Bean(properties="name")
-public record WithBeanc(String name, int age) {
- @Beanc(properties="name")
- public WithBeanc(String name) {
+@Marshalled(properties="name")
+public record WithMarshalledCtor(String name, int age) {
+ @MarshalledCtor(properties="name")
+ public WithMarshalledCtor(String name) {
this(name, 0); // Default age to 0
}
}
```
-When using `@Beanc` with a non-canonical constructor on a record, use
-<a href="/site/apidocs/org/apache/juneau/annotation/Bean.html#properties()"
target="_blank">@Bean(properties)</a> to
+When using `@MarshalledCtor` with a non-canonical constructor on a record, use
+<a
href="/site/apidocs/org/apache/juneau/annotation/Marshalled.html#properties()"
target="_blank">@Marshalled(properties)</a> to
limit the visible properties to match the constructor parameters.
:::info See Also
diff --git a/pages/topics/02.04.06.BeanIgnoreAnnotation.md
b/pages/topics/02.04.06.BeanIgnoreAnnotation.md
index bb6731e0d3..efb01b4a78 100644
--- a/pages/topics/02.04.06.BeanIgnoreAnnotation.md
+++ b/pages/topics/02.04.06.BeanIgnoreAnnotation.md
@@ -1,37 +1,51 @@
---
-title: "@BeanIgnore Annotation"
+title: "@MarshalledIgnore Annotation"
slug: BeanIgnoreAnnotation
---
-The <a href="/site/apidocs/org/apache/juneau/annotation/BeanIgnore.html"
target="_blank">@BeanIgnore</a> annotation is used to ignore classes,
-fields, and methods from being interpreted as beans or bean components.
+The <a href="/site/apidocs/org/apache/juneau/annotation/MarshalledIgnore.html"
target="_blank">@MarshalledIgnore</a> annotation is used to ignore fields and
+methods from being interpreted as bean components, and to suppress
serialization of a class entirely.
-When applied to classes, objects will be converted to strings even though they
look like beans.
-
-```java
-// Not really a bean! Use toString() instead!
-@BeanIgnore
-public class MyBean {...}
-```
-
-When applied to fields and getters/setters, they will be ignored as bean
properties.
+When applied to **fields and getters/setters**, they will be ignored as bean
properties.
```java
public class MyBean {
// Not a bean property!
- @BeanIgnore
+ @MarshalledIgnore
public String foo;
// Not a bean property!
- @BeanIgnore
+ @MarshalledIgnore
public String getBar() {...}
}
```
+When applied to a **class**, objects of that type are suppressed during
serialization (output as `null`).
+
+```java
+// Suppressed entirely — serializes as null.
+@MarshalledIgnore
+public class MyType {...}
+```
+
+:::note Migration
+In versions prior to 9.5, `@BeanIgnore` on a class caused the object to be
serialized via `toString()` rather than as a bean. The new `@MarshalledIgnore`
on a class instead outputs `null`.
+
+If you want the old `toString()` serialization behavior, use
`@Marshalled(as=MarshalledAs.STRING)` instead:
+
+```java
+// Serialize as toString() value (old @BeanIgnore-on-class behavior)
+@Marshalled(as=MarshalledAs.STRING)
+public class MyType {
+ @Override public String toString() { return "my-value"; }
+}
+```
+:::
+
### Private fields and accessors (`ignoreAccessors`)
-By default, `@BeanIgnore` on a **field** only excludes that field from
**field-based** bean discovery. Public (or otherwise visible)
**getters/setters** can still expose the same logical property—for example when
`beanFieldVisibility` is `NONE` and only methods are used. That matches
patterns such as `@BeanIgnore` on private `f5`…`f8` with public `getF5()` while
still serializing `f5` via the getter.
+By default, `@MarshalledIgnore` on a **field** only excludes that field from
**field-based** bean discovery. Public (or otherwise visible)
**getters/setters** can still expose the same logical property—for example when
`beanFieldVisibility` is `NONE` and only methods are used. That matches
patterns such as `@MarshalledIgnore` on private `f5`…`f8` with public `getF5()`
while still serializing `f5` via the getter.
To **also** exclude the matching JavaBean accessor pair from metadata (so the
property does not appear in serialization or parsing), set **`ignoreAccessors =
true`** on the field annotation:
@@ -41,7 +55,7 @@ public class MyBean {
public String visible = "ok";
// Hidden from Juneau bean metadata: no "foo" in serialization/parsing
- @BeanIgnore(ignoreAccessors = true)
+ @MarshalledIgnore(ignoreAccessors = true)
private String foo = "secret";
public String getFoo() {
@@ -54,17 +68,17 @@ public class MyBean {
}
```
-The logical property name is derived from the field the same way as for
visible fields: `@Beanp` / `@Name` on the field, if present, otherwise the bean
context’s `PropertyNamer` applied to the field name. That name must match the
accessor-derived property name (e.g. field `foo` with `getFoo`/`setFoo`).
+The logical property name is derived from the field the same way as for
visible fields: `@MarshalledProp` / `@Name` on the field, if present, otherwise
the marshalling context's `PropertyNamer` applied to the field name. That name
must match the accessor-derived property name (e.g. field `foo` with
`getFoo`/`setFoo`).
## Java Records
Ignoring individual record components is not supported during parsing.
Because records are immutable, all components
-must be provided to the canonical constructor. Applying `@BeanIgnore` to a
record component's accessor method or
+must be provided to the canonical constructor. Applying `@MarshalledIgnore`
to a record component's accessor method or
field will exclude it from serialization output, but the parser will be unable
to instantiate the record if the
component value is missing from the input.
If you need to omit components during parsing, use
-<a href="/site/apidocs/org/apache/juneau/annotation/Beanc.html"
target="_blank">@Beanc</a> with a non-canonical
+<a href="/site/apidocs/org/apache/juneau/annotation/MarshalledCtor.html"
target="_blank">@MarshalledCtor</a> with a non-canonical
constructor that provides defaults for the omitted components.
:::info See Also
diff --git a/pages/topics/10.04.03.JavaMethodParameters.md
b/pages/topics/10.04.03.JavaMethodParameters.md
index da9bf1e4c0..53e44a72b9 100644
--- a/pages/topics/10.04.03.JavaMethodParameters.md
+++ b/pages/topics/10.04.03.JavaMethodParameters.md
@@ -16,7 +16,7 @@ Java methods can contain any of the following parameters in
any order:
<node-1>**Parsed request header values:**</node-1>
<node-2><javac-class><a
href="/site/apidocs/org/apache/juneau/http/header/Accept.html"
target="_blank">Accept</a></javac-class> <javac-class><a
href="/site/apidocs/org/apache/juneau/http/header/AcceptCharset.html"
target="_blank">AcceptCharset</a></javac-class> <javac-class><a
href="/site/apidocs/org/apache/juneau/http/header/AcceptEncoding.html"
target="_blank">AcceptEncoding</a></javac-class> <javac-class><a
href="/site/apidocs/org/apache/juneau/http/header/AcceptLanguage.html" target=
[...]
<node-1>**Context values:**</node-1>
-<node-2><javac-class><a
href="/site/apidocs/org/apache/juneau/BeanContext.html"
target="_blank">BeanContext</a></javac-class> <javac-class><a
href="/site/apidocs/org/apache/juneau/rest/logger/CallLogger.html"
target="_blank">CallLogger</a></javac-class> <javac-class><a
href="/site/apidocs/org/apache/juneau/config/Config.html"
target="_blank">Config</a></javac-class> <javac-class><a
href="/site/apidocs/org/apache/juneau/rest/debug/DebugEnablement.html"
target="_blank">DebugEnablement</a>< [...]
+<node-2><javac-class><a
href="/site/apidocs/org/apache/juneau/MarshallingContext.html"
target="_blank">MarshallingContext</a></javac-class> <javac-class><a
href="/site/apidocs/org/apache/juneau/rest/logger/CallLogger.html"
target="_blank">CallLogger</a></javac-class> <javac-class><a
href="/site/apidocs/org/apache/juneau/config/Config.html"
target="_blank">Config</a></javac-class> <javac-class><a
href="/site/apidocs/org/apache/juneau/rest/debug/DebugEnablement.html"
target="_blank">DebugE [...]
<node-0>**Annotated parameters:**</node-0>
<node-1><javac-annotation><a
href="/site/apidocs/org/apache/juneau/rest/annotation/Attr.html"
target="_blank">Attr</a></javac-annotation> <javac-annotation><a
href="/site/apidocs/org/apache/juneau/http/annotation/Content.html"
target="_blank">Content</a></javac-annotation> <javac-annotation><a
href="/site/apidocs/org/apache/juneau/http/annotation/Path.html"
target="_blank">Path</a></javac-annotation> <javac-annotation><a
href="/site/apidocs/org/apache/juneau/http/annotation/FormData.html [...]
</tree>
@@ -49,7 +49,7 @@ public String doGetExample1(
```
:::
-Additional parameter types can be defined via the annotation <a
href="/site/apidocs/org/apache/juneau/rest/annotation/Rest.html#restOpArgs()"
target="_blank">Rest.restOpArgs()</a> or by supplying a named bean via <a
href="/site/apidocs/org/apache/juneau/rest/annotation/RestInject.html"
target="_blank">@RestInject</a>.
+Additional parameter types can be defined via the annotation <a
href="/site/apidocs/org/apache/juneau/rest/annotation/Rest.html#restOpArgs()"
target="_blank">Rest.restOpArgs()</a> or by supplying a named bean via <a
href="/site/apidocs/org/apache/juneau/commons/inject/Bean.html"
target="_blank">@Bean</a>.
:::tip Example
```java
diff --git a/pages/topics/23.01.V9.5-migration-guide.md
b/pages/topics/23.01.V9.5-migration-guide.md
index 9aa619252b..8b3f6c2480 100644
--- a/pages/topics/23.01.V9.5-migration-guide.md
+++ b/pages/topics/23.01.V9.5-migration-guide.md
@@ -12,23 +12,77 @@ teams jumping from 9.1 (or earlier) directly to 9.5 have a
single reference.
| Old | New |
|-----|-----|
| `@Rest(allowedHeaderParams="NONE")` / `@Rest(allowedMethodHeaders="NONE")` /
`@Rest(allowedMethodParams="NONE")` — the literal string `"NONE"` was used to
suppress inheriting the attribute from a parent class. | The `"NONE"` sentinel
has been removed. Use the standard <a
href="/site/apidocs/org/apache/juneau/rest/annotation/Rest.html#noInherit()"
target="_blank">Rest.noInherit</a> array to suppress inheritance, e.g.
`@Rest(noInherit={"allowedHeaderParams"})`. The same substitution appl [...]
-| `RestContext.Builder` — large stateful builder with dozens of fluent setters
(`allowedHeaderParams(String)`, `encoders(Class<?>...)`,
`callLogger(Class<?>)`, etc.). | **Removed.** All configuration now flows
through `@Rest(...)` annotation attributes or <a
href="/site/apidocs/org/apache/juneau/rest/annotation/RestInject.html"
target="_blank">RestInject</a>-annotated methods/fields supplying named beans
to the REST bean store. See the per-setting migration table in the 9.5 release
notes. |
-| `RestOpContext.Builder` — large stateful builder with dozens of fluent
setters. | **Removed.** Same replacement model as `RestContext.Builder` —
`@RestOp(...)` / `@RestGet(...)` / `@RestPost(...)` annotation attributes and
`@RestInject` beans. |
-| Sub-builder chaining via `RestContext.Builder.encoders()`, `.parsers()`,
`.serializers()`, etc. (returned mutable child builders that user code chained
fluent calls on). | **Removed.** Compose by supplying a fully-built
`EncoderSet` / `ParserSet` / `SerializerSet` bean via
`@RestInject(name="encoders" / "parsers" / "serializers" / ...)`, or rely on
the `@Rest(encoders=..., parsers=..., serializers=...)` class array attributes.
|
-| `static Optional<X> createXxx(BeanStore, Resource, Logger, ...)` magic-named
static factory methods on the resource class — used to supply `EncoderSet`,
`ParserSet`, `SerializerSet`, `BeanContext`, `CallLogger`, `DebugEnablement`,
`StaticFiles`, `SwaggerProvider`, `HeaderList`, `NamedAttributeMap`, etc. The
framework discovered these by name via `BeanCreateMethodFinder` reflection. |
Annotate the same method with <a
href="/site/apidocs/org/apache/juneau/rest/annotation/RestInject.html" [...]
+| `RestContext.Builder` — large stateful builder with dozens of fluent setters
(`allowedHeaderParams(String)`, `encoders(Class<?>...)`,
`callLogger(Class<?>)`, etc.). | **Removed.** All configuration now flows
through `@Rest(...)` annotation attributes or <a
href="/site/apidocs/org/apache/juneau/commons/inject/Bean.html"
target="_blank">@Bean</a>-annotated methods/fields supplying named beans to the
REST bean store. See the per-setting migration table in the 9.5 release notes. |
+| `RestOpContext.Builder` — large stateful builder with dozens of fluent
setters. | **Removed.** Same replacement model as `RestContext.Builder` —
`@RestOp(...)` / `@RestGet(...)` / `@RestPost(...)` annotation attributes and
`@Bean` beans. |
+| Sub-builder chaining via `RestContext.Builder.encoders()`, `.parsers()`,
`.serializers()`, etc. (returned mutable child builders that user code chained
fluent calls on). | **Removed.** Compose by supplying a fully-built
`EncoderSet` / `ParserSet` / `SerializerSet` bean via `@Bean(name="encoders" /
"parsers" / "serializers" / ...)`, or rely on the `@Rest(encoders=...,
parsers=..., serializers=...)` class array attributes. |
+| `static Optional<X> createXxx(BeanStore, Resource, Logger, ...)` magic-named
static factory methods on the resource class — used to supply `EncoderSet`,
`ParserSet`, `SerializerSet`, `MarshallingContext`, `CallLogger`,
`DebugEnablement`, `StaticFiles`, `SwaggerProvider`, `HeaderList`,
`NamedAttributeMap`, etc. The framework discovered these by name via
`BeanCreateMethodFinder` reflection. | Annotate the same method with <a
href="/site/apidocs/org/apache/juneau/commons/inject/Bean.html" [...]
| `RestContext.Builder.defaultAccept(String)` / `defaultContentType(String)`
convenience setters. | Use the new `@Rest(defaultAccept="...",
defaultContentType="...")` annotation attributes (also available on `@RestOp` /
`@RestGet` / etc.). They expand internally into `Accept` / `Content-Type`
entries on `defaultRequestHeaders`, preserving the semantic. |
| `RestOpContext.Builder.dotAll()` flag. | **Removed.** The flag is now
inferred from the URL pattern itself — a path containing `**` or `/.*` implies
`dotAll=true`. Delete the call; the URL pattern dictates behavior. |
| `RestOp(defaultCharset)` / `RestOp(maxInput)` resolved by falling back to
`RestContext`-level builder values. | Both fall back to the resource class's
`@Rest(defaultCharset)` / `@Rest(maxInput)` annotation values directly (walking
the class hierarchy, governed by `@Rest(noInherit={...})`). The
`RestContext`-level builder fields/getters have been removed; they were only
ever populated by the now-deleted builder. |
| Lifecycle method getter return types — `RestContext.getStartCallMethods()`,
`getEndCallMethods()`, `getPostCallMethods()` (and similar for pre-call etc.)
returned `MethodInvoker[]` for some lists and `MethodList` for others. | All
seven lifecycle method lists now return `MethodList` for consistency. Callers
that iterated `MethodInvoker[]` should migrate to `MethodList`'s iteration API
(or call `.toArray(new MethodInvoker[0])` if they truly need an array). |
-| Reusable bean definitions had to be declared inline on each REST resource
class via `@RestInject`-annotated methods/fields, with no first-class way to
share them across multiple resources without using a full DI container like
Spring. | New `@Rest(beans={MyConfig.class, ...})` attribute. The named classes
are scanned for `@RestInject` members and their beans are contributed to the
REST bean store, Spring-`@Configuration`-style. `@RestInject` on the resource
class still works as before; [...]
+| Reusable bean definitions had to be declared inline on each REST resource
class via `@Bean`-annotated methods/fields, with no first-class way to share
them across multiple resources without using a full DI container like Spring. |
New `@Rest(beans={MyConfig.class, ...})` attribute. The named classes are
scanned for `@Bean` members and their beans are contributed to the REST bean
store, Spring-`@Configuration`-style. `@Bean` on the resource class still works
as before; `beans=` is purel [...]
| `RestContext.create(resourceClass, parentContext,
servletConfig).init(supplier).path(p).children(c).build()` static-factory chain
— used by mock REST clients, child-resource bootstrap, and
`RestServlet.init(ServletConfig)`. | **Removed.** Use the new <a
href="/site/apidocs/org/apache/juneau/rest/RestContext.html#%3Cinit%3E(org.apache.juneau.rest.RestContextInit)"
target="_blank">`new RestContext(RestContextInit init)`</a> constructor with a
<a href="/site/apidocs/org/apache/juneau/rest [...]
-| Resource classes could expose a `public MyResource(RestContext.Builder
builder) throws Exception { builder.path(...); builder.children(...); }`
constructor and have the framework inject the in-flight builder so the resource
could imperatively configure itself. | **Removed.** The Builder-injection
protocol is gone. Resource classes must declare configuration declaratively via
`@Rest(...)` annotation attributes and `@RestInject` members, or pass values
through `RestContextInit` when cons [...]
-| Per-operation `@RestInit public void init(RestOpContext.Builder b) { ... }`
hook — the framework discovered every `@RestInit` method whose parameter list
contained `RestOpContext.Builder` and invoked it once per `@RestOp`-annotated
method, threading the in-flight per-op builder so the hook could imperatively
customize a single operation's context. | **Removed.** The per-op
`@RestInit(RestOpContext.Builder)` injection protocol is gone. All
operation-level configuration is now expressed [...]
+| Resource classes could expose a `public MyResource(RestContext.Builder
builder) throws Exception { builder.path(...); builder.children(...); }`
constructor and have the framework inject the in-flight builder so the resource
could imperatively configure itself. | **Removed.** The Builder-injection
protocol is gone. Resource classes must declare configuration declaratively via
`@Rest(...)` annotation attributes and `@Bean` members, or pass values through
`RestContextInit` when constructi [...]
+| Per-operation `@RestInit public void init(RestOpContext.Builder b) { ... }`
hook — the framework discovered every `@RestInit` method whose parameter list
contained `RestOpContext.Builder` and invoked it once per `@RestOp`-annotated
method, threading the in-flight per-op builder so the hook could imperatively
customize a single operation's context. | **Removed.** The per-op
`@RestInit(RestOpContext.Builder)` injection protocol is gone. All
operation-level configuration is now expressed [...]
| `RestOpContext.create(java.lang.reflect.Method, RestContext)` static factory
+ the fluent `.beanStore(...).type(...).build()` chain — used internally by
`RestContext` and (rarely) by user code building one-off `RestOpContext`
instances. | **Removed.** The two internal callers in
`RestContext.Builder.createRestOperations` migrated to direct constructor
invocation: `new RestOpContext(method, context)` for the standard path and `new
RrpcRestOpContext(method, context)` for the RRPC special [...]
-| Class-level `@RestInit public void init(RestContext.Builder b) { ... }` hook
— the framework added the in-flight `RestContext.Builder` to the resource's
bean store so any `@RestInit` method that declared a `RestContext.Builder`
parameter received it and could imperatively configure the resource-level
context (`builder.path(...)`, `builder.children(...)`, `builder.encoders(...)`,
etc.). | **Removed.** The class-level Builder-injection protocol is gone —
`RestContext.Builder` is no longe [...]
+| Class-level `@RestInit public void init(RestContext.Builder b) { ... }` hook
— the framework added the in-flight `RestContext.Builder` to the resource's
bean store so any `@RestInit` method that declared a `RestContext.Builder`
parameter received it and could imperatively configure the resource-level
context (`builder.path(...)`, `builder.children(...)`, `builder.encoders(...)`,
etc.). | **Removed.** The class-level Builder-injection protocol is gone —
`RestContext.Builder` is no longe [...]
-| Custom annotation appliers — user code that subclassed the internal
`AnnotationApplier<Rest, RestContext.Builder>` (or `AnnotationApplier<RestOp,
RestOpContext.Builder>`) to extend the annotation-processing pass (the
`apply(AnnotationInfo<A>, B builder)` hook invoked once per annotation during
context construction). | **Removed.** The builder-based apply-pass is gone;
`RestAnnotation.Apply` (`RestContextApply`) is now a package-private nested
class inside `RestContext` and is not exten [...]
+| Custom annotation appliers — user code that subclassed the internal
`AnnotationApplier<Rest, RestContext.Builder>` (or `AnnotationApplier<RestOp,
RestOpContext.Builder>`) to extend the annotation-processing pass (the
`apply(AnnotationInfo<A>, B builder)` hook invoked once per annotation during
context construction). | **Removed.** The builder-based apply-pass is gone;
`RestAnnotation.Apply` (`RestContextApply`) is now a package-private nested
class inside `RestContext` and is not exten [...]
| Custom `RestAnnotation.create(...)` / `RestOpAnnotation.create(...)`
builder-of-builders patterns — programmatic construction of `@Rest` / `@RestOp`
annotation proxies used to feed synthetic annotations into the builder
apply-pass (common in test fixtures and extension libraries). | The annotation
proxy builders still exist for test use (`RestAnnotation.create()` /
`RestOpAnnotation.create()` are still available via annotation-test helpers),
but they no longer feed into a builder apply [...]
+## Bean→Marshalled Renames
+
+### Annotation Renames
+
+| Old | New | Notes |
+|-----|-----|-------|
+| `import org.apache.juneau.annotation.Bean;` | `import
org.apache.juneau.annotation.Marshalled;` | Marshall-level annotation renamed. |
+| `@Bean(properties=...)` | `@Marshalled(properties=...)` | All `@Bean`
attributes are available on `@Marshalled`. |
+| `@Bean(interceptor=...)` | `@Marshalled(interceptor=...)` | Same attribute,
new annotation name. |
+| `@Bean(typeName=...)` etc. | `@Marshalled(typeName=...)` | All other `@Bean`
attributes likewise. |
+| `@BeanApply` | `@MarshalledApply` | Config-class applier for `@Marshalled`. |
+| `@Beanp` / `@Beanp(name=...)` | `@MarshalledProp` /
`@MarshalledProp(name=...)` | Bean *property* annotation renamed. |
+| `@BeanpApply` | `@MarshalledPropApply` | Config-class applier for
`@MarshalledProp`. |
+| `@Beanc` / `@Beanc(properties=...)` | `@MarshalledCtor` /
`@MarshalledCtor(properties=...)` | Constructor mapping annotation renamed. |
+| `@BeancApply` | `@MarshalledCtorApply` | Config-class applier for
`@MarshalledCtor`. |
+| `@BeanIgnore` on a **field or method** | `@MarshalledIgnore` on the same
target | Field/method-level semantics unchanged. |
+| `@BeanIgnore` on a **class** (→ toString) | `@Marshalled(as=STRING)` | Old
behavior was toString(); new `@MarshalledIgnore` on a class outputs `null`.
Migrate to `@Marshalled(as=STRING)` to preserve toString behavior. |
+| `@BeanIgnoreApply` | `@MarshalledIgnoreApply` | Config-class applier for
`@MarshalledIgnore`. |
+| `@BeanConfig` | `@MarshalledConfig` | Config-class annotation renamed. |
+| `import org.apache.juneau.rest.annotation.RestInject;` | `import
org.apache.juneau.commons.inject.Bean;` | `@RestInject` renamed to `@Bean` and
moved to `juneau-commons`. |
+| `@RestInject` | `@Bean` | All semantics identical; only package and name
changed. |
+
+### Engine Type Renames
+
+| Old | New |
+|-----|-----|
+| `BeanContext` | `MarshallingContext` |
+| `BeanContext.DEFAULT` | `MarshallingContext.DEFAULT` |
+| `BeanContextable` | `MarshallingContextable` |
+| `BeanSession` | `MarshallingSession` |
+| `BeanTraverseContext` | `MarshallingTraverseContext` |
+| `BeanTraverseSession` | `MarshallingTraverseSession` |
+| `BeanRecursionException` | `MarshallingRecursionException` |
+| `BeanInterceptor` | `MarshallingInterceptor` |
+| `BeanStringSwap` | `MarshallingStringSwap` — also see
`@Marshalled(as=STRING)` for the common case |
+| `BeanContextConverter` | `MarshallingContextConverter` |
+| `BeanDefMapper` | `MarshallingDefMapper` |
+
+### New `@Marshalled(as=STRING)` Usage
+
+If you previously used `BeanStringSwap` to serialize a type via its
`toString()` method, you can now use the annotation directly:
+
+```java
+// Before
+public class MyType extends BeanStringSwap { ... }
+// or registered via BeanContext.Builder.swaps(MyTypeSwap.class)
+
+// After — annotate the class directly
+@Marshalled(as=STRING)
+public class MyType {
+ @Override public String toString() { return "my-string-form"; }
+}
+```
+
<!-- Additional rows will be populated as 9.5 breaking changes land. See
todo/TODO-17 for the
- ongoing 9.5.0 audit. -->
+ongoing 9.5.0 audit. -->