Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .agents/languages/java.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ Load this file when changing anything under `java/` or when Java drives a cross-

- Run all Maven commands from within `java/`.
- Changes under `java/` must pass code style checks and tests.
- When changes are limited to `fory-json` or `fory-format`, do not run `fory-core`
tests. Install the changed module and its reactor dependencies with
`-am install -DskipTests`, then run `test` with only the changed module selected
and without `-am`. In particular, never use `-pl fory-json -am test` or
`-pl fory-format -am test`, because Maven propagates the test phase to
`fory-core`.
- If tests already passed and the only later change is Maven Spotless formatting, do not rerun
tests solely because of that formatting pass. Verify formatting with `spotless:check` and inspect
the diff/status instead.
Expand Down
35 changes: 17 additions & 18 deletions docs/guide/java/json-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,11 @@ ForyJson json =
.build();
```

`withConcurrencyLevel` controls reusable operation states, not a caller limit. Extra concurrent
operations use temporary state rather than one global lock.
`withConcurrencyLevel` sets the maximum number of root operations that execute concurrently.
Additional callers wait until one of those fixed execution states is available. Root APIs on one
`ForyJson` instance are not reentrant: a custom codec must continue through the concrete reader or
writer passed to it instead of calling `toJson`, `toJsonBytes`, `writeJsonTo`, or `fromJson` on that
instance.

## Object mapping

Expand Down Expand Up @@ -286,7 +289,7 @@ are rejected.
| `withClassLoader` | Snapshotted context loader, then Fory loader | Resolve annotation subtype class names |
| `maxDepth` | `20` | Maximum nested object/array depth |
| `withMaxCachedFieldNames` | `DEFAULT_MAX_CACHED_FIELD_NAMES` (`8192`) | Field-name cache entries per reader; zero disables it |
| `withConcurrencyLevel` | `max(1, 2 * processors)` | Reusable operation-state count |
| `withConcurrencyLevel` | `max(1, 2 * processors)` | Maximum concurrent root operations |
| `withBufferSizeLimitBytes` | 2 MiB | Reusable capacity retained by each pooled writer |
| `registerCodec` | None | Exact-class complete-value codec |
| `registerMixin` | None | Annotation Mixin for its exact declared target |
Expand Down Expand Up @@ -682,12 +685,12 @@ The complete group occupies one position in parent serialization order. Position
is preserved inside the group. Input matches parent fixed properties first, flattened properties
second, and dynamic Any members last.

Fory rejects final-name or name-hash collisions, recursive chains made only of unwrapped
properties, parameterized children, JSON Any children, polymorphic or custom-codec child roots,
and scalar, array, collection, or Map children. Flatten Maps with `JsonAnyProperty`,
`JsonAnyGetter`, or `JsonAnySetter`. An unwrapped property cannot use `JsonProperty.value`, a
non-default `JsonProperty.include`, or `JsonCodec`; ordinary leaf properties inside the child keep
their normal annotations.
Fory rejects duplicate final names, recursive chains made only of unwrapped properties,
parameterized children, JSON Any children, polymorphic or custom-codec child roots, and scalar,
array, collection, or Map children. Flatten Maps with `JsonAnyProperty`, `JsonAnyGetter`, or
`JsonAnySetter`. An unwrapped property cannot use `JsonProperty.value`, a non-default
`JsonProperty.include`, or `JsonCodec`; ordinary leaf properties inside the child keep their normal
annotations.

### Dynamic object members

Expand Down Expand Up @@ -760,15 +763,11 @@ Dynamic keys are emitted unchanged in Map iteration order. A null Map emits noth
Map value emits JSON null regardless of fixed-property null settings. Null and non-String output
keys are rejected. Raw Maps, wildcard or unresolved keys, and non-String key types are invalid.
Declared fixed members, including members excluded from reading, are not delivered to an Any
input. Output keys whose Fory field-name hash conflicts with a fixed property are rejected,
including differently spelled hash collisions. Fory does not inspect an Any Map for a key whose
name or Fory field-name hash conflicts with an inline subtype discriminator. An exact-name output
key emits a duplicate JSON member; on input, a differently spelled hash collision is classified as
the discriminator by the child field table. Applications must keep dynamic keys distinct from the
active discriminator by both name and hash. Repeated unknown names replace the Map value; an
any-setter is called for every occurrence. Fixed input lookup is also hash-based, so a differently
spelled colliding name follows the fixed member instead of Any handling. Escaped input names are
decoded before delivery.
input. An output key that conflicts with a fixed property is rejected. Fory does not inspect an Any
Map for a key that duplicates an inline subtype discriminator; such a key emits a duplicate JSON
member. Applications must keep dynamic keys distinct from the active discriminator. Repeated
unknown names replace the Map value; an any-setter is called for every occurrence. Escaped input
names are decoded before delivery.

### `JsonCreator`

Expand Down
35 changes: 16 additions & 19 deletions java/fory-json/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,11 @@ ForyJson json =
.build();
```

`withConcurrencyLevel` configures the number of reusable operation states, not a maximum number of
concurrent callers. When all reusable states are busy, Fory JSON creates a temporary state rather
than serializing callers through one global lock.
`withConcurrencyLevel` sets the maximum number of root operations that execute concurrently.
Additional callers wait until one of those fixed execution states is available. Root APIs on one
`ForyJson` instance are not reentrant: a custom codec must continue through the concrete reader or
writer passed to it instead of calling `toJson`, `toJsonBytes`, `writeJsonTo`, or `fromJson` on that
instance.

## Java object mapping

Expand Down Expand Up @@ -360,7 +362,7 @@ original key type. Null map keys are rejected.
| `withClassLoader(loader)` | Snapshotted thread context loader, then Fory JSON loader | Resolve annotation-declared subtype class names |
| `maxDepth(int)` | `20` | Maximum nested object/array depth for reads and writes |
| `withMaxCachedFieldNames(int)` | `DEFAULT_MAX_CACHED_FIELD_NAMES` (`8192`) | Field-name cache entries per reader; zero disables caching |
| `withConcurrencyLevel(int)` | `max(1, 2 * processors)` | Number of reusable concurrent operation states |
| `withConcurrencyLevel(int)` | `max(1, 2 * processors)` | Maximum concurrent root operations |
| `withBufferSizeLimitBytes(int)` | 2 MiB | Maximum reusable capacity retained by each pooled writer |
| `registerCodec(type, codec)` | None | Replace the exact class's complete JSON codec |
| `registerMixin(mixinType)` | None | Apply one annotation Mixin to its exact declared target |
Expand Down Expand Up @@ -754,12 +756,11 @@ position it, and `JsonPropertyOrder` selects it by Java logical property name. T
property order remains intact. Parent fields are matched before flattened fields, which are matched
before dynamic Any handling.

Fory rejects duplicate or hash-colliding final names, recursive chains made only of unwrapped
properties, parameterized children, JSON Any children, polymorphic or custom-codec child roots,
and scalar, array, collection, or Map children. Use `JsonAnyProperty`, `JsonAnyGetter`, or
`JsonAnySetter` to flatten a Map. `JsonProperty.value`, non-default `JsonProperty.include`, and
`JsonCodec` are not valid on an unwrapped property; ordinary child leaf properties may still use
them.
Fory rejects duplicate final names, recursive chains made only of unwrapped properties,
parameterized children, JSON Any children, polymorphic or custom-codec child roots, and scalar,
array, collection, or Map children. Use `JsonAnyProperty`, `JsonAnyGetter`, or `JsonAnySetter` to
flatten a Map. `JsonProperty.value`, non-default `JsonProperty.include`, and `JsonCodec` are not
valid on an unwrapped property; ordinary child leaf properties may still use them.

### Dynamic object members

Expand Down Expand Up @@ -854,15 +855,11 @@ Dynamic keys are exact JSON member names and retain Map iteration order. A null
members, and a null Map value writes JSON null regardless of fixed-property null settings. Null and
non-String output keys are rejected. Raw Maps, wildcard or unresolved keys, and non-String key
types are invalid. Declared fixed members, including members excluded from reading, are not
delivered to an Any input. An output key is rejected when its Fory field-name hash conflicts with a
fixed property; this also covers differently spelled hash collisions. Fory does not inspect an Any
Map for a key whose name or Fory field-name hash conflicts with an inline subtype discriminator. An
exact-name output key writes a duplicate JSON member; on input, a differently spelled hash
collision is classified as the discriminator by the child field table. Applications must keep
dynamic keys distinct from the active discriminator by both name and hash. Fixed input lookup is
also hash-based, so a differently spelled colliding name follows the fixed member instead of Any
handling. Repeated unknown input names replace the prior Map value, while an any-setter is invoked
for every occurrence. Escaped input names are decoded before delivery.
delivered to an Any input. An output key that conflicts with a fixed property is rejected. Fory
does not inspect an Any Map for a key that duplicates an inline subtype discriminator; such a key
writes a duplicate JSON member. Applications must keep dynamic keys distinct from the active
discriminator. Repeated unknown input names replace the prior Map value, while an any-setter is
invoked for every occurrence. Escaped input names are decoded before delivery.

### `JsonCreator`

Expand Down
Loading
Loading