---
title: JSON Support
sidebar_position: 19
id: json_support
license: |
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
---

Fory JSON is Apache Fory's thread-safe Java JSON codec. It supports Java objects, records,
immutable creator-based classes, common JDK types, generic containers, custom complete-value
codecs, and finite annotation-declared polymorphism through interpreted and runtime-generated
codecs.

Fory JSON is separate from Fory's binary native and xlang protocols. Use JSON for interoperable
text payloads such as HTTP APIs, browser traffic, logs, and configuration. Use the binary protocol
when you need reference identity, circular graphs, cross-language schema metadata, or Fory's
binary-only features.

## Requirements and installation

Fory JSON supports Java 8 and later on standard JDKs, GraalVM native images, and Android. Java
records are supported on Java 17 and later.

Fory JSON is available from Maven Central.

Maven:

```xml
<dependency>
  <groupId>org.apache.fory</groupId>
  <artifactId>fory-json</artifactId>
  <version>1.4.0</version>
</dependency>
```

Gradle:

```kotlin
implementation("org.apache.fory:fory-json:1.4.0")
```

Keep all Fory modules on the same version.

### JDK 25 and later

Open `java.lang.invoke` to Fory core. On the classpath:

```bash
--add-opens=java.base/java.lang.invoke=ALL-UNNAMED
```

On the module path:

```bash
--add-opens=java.base/java.lang.invoke=org.apache.fory.core
```

Fory JSON's JPMS module name is `org.apache.fory.json`.

## Quick start

Create one `ForyJson` instance and reuse it. It is thread-safe and has no close lifecycle.

```java
import java.nio.charset.StandardCharsets;
import org.apache.fory.json.ForyJson;

public final class JsonExample {
  private static final ForyJson JSON = ForyJson.builder().build();

  public static final class User {
    public long id;
    public String name;

    public User() {}

    User(long id, String name) {
      this.id = id;
      this.name = name;
    }
  }

  public static void main(String[] args) {
    User input = new User(7, "Alice");
    String text = JSON.toJson(input);
    byte[] utf8 = JSON.toJsonBytes(input);

    User fromText = JSON.fromJson(text, User.class);
    User fromUtf8 = JSON.fromJson(utf8, User.class);

    System.out.println(text);
    System.out.println(new String(utf8, StandardCharsets.UTF_8));
    System.out.println(fromText.name + " / " + fromUtf8.name);
  }
}
```

Unknown input properties are skipped unless a read-enabled Any field or any-setter receives them.
Null object properties are omitted by default. Default JSON member discovery order is not a
compatibility contract; use `JsonPropertyOrder` or `JsonProperty.index` when emitted member order
must be explicit.

## Reading and writing

Fory JSON supports String and UTF-8 byte input/output. There is no `InputStream` parsing API.

| Operation            | Runtime type              | Declared `Class`                | Declared `TypeRef`                 |
| -------------------- | ------------------------- | ------------------------------- | ---------------------------------- |
| String output        | `toJson(value)`           | `toJson(value, type)`           | `toJson(value, typeRef)`           |
| UTF-8 bytes          | `toJsonBytes(value)`      | `toJsonBytes(value, type)`      | `toJsonBytes(value, typeRef)`      |
| UTF-8 `OutputStream` | `writeJsonTo(value, out)` | `writeJsonTo(value, type, out)` | `writeJsonTo(value, typeRef, out)` |
| String input         | -                         | `fromJson(text, type)`          | `fromJson(text, typeRef)`          |
| UTF-8 input          | -                         | `fromJson(bytes, type)`         | `fromJson(bytes, typeRef)`         |

Parsing consumes exactly one value and rejects trailing non-whitespace. String and byte-array
outputs are detached from internal buffers.

`writeJsonTo` buffers the complete document, performs one `OutputStream.write`, and neither flushes
nor closes the stream. It is not incremental streaming. I/O failures are wrapped in
`ForyJsonException`.

### Generic and declared types

Use `TypeRef` for generic roots:

```java
import java.util.List;
import org.apache.fory.reflect.TypeRef;

TypeRef<List<User>> usersType = new TypeRef<List<User>>() {};
List<User> users = json.fromJson("[{\"id\":7,\"name\":\"Alice\"}]", usersType);
String encoded = json.toJson(users, usersType);
```

Typed writes require fully bound types and reject wildcards and type variables. Values must be
assignable to the declared raw type. The declared schema controls serialization, including nested
generic element types and closed subtype metadata.

Use a declared base type when it owns `JsonSubTypes`:

```java
Shape shape = new Circle(2);

json.toJson(shape);              // Concrete runtime representation
json.toJson(shape, Shape.class); // Configured Shape subtype representation
```

For `List<Shape>`, use `new TypeRef<List<Shape>>() {}` so each element retains the declared subtype
schema.

## Thread safety and code generation

`ForyJson` is immutable and thread-safe after `build()`. Registered and annotation-selected
`JsonValueCodec` instances and type checkers are shared and must also be thread-safe.

Code generation and asynchronous compilation are enabled by default. Disable them for diagnostics
or environments that prohibit runtime compilation:

```java
ForyJson json =
    ForyJson.builder()
        .withCodegen(false)
        .withAsyncCompilation(false)
        .build();
```

`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

Default discovery merges members with the same Java logical property name:

- eligible instance fields across the hierarchy, regardless of Java visibility;
- public non-static `getX()` and boolean `isX()` getters;
- public non-static void `setX(value)` setters.

Static, transient, synthetic, and `Class<?>` fields are excluded. Class-valued accessors and
`getClass()` are excluded. An annotation on an ineligible member fails rather than becoming a
silent no-op.

An ordinary final field is a write source but not a mutable read sink. Use a record, `JsonCreator`,
or custom codec for immutable construction. Records use their canonical constructor.

Enable field-only discovery with:

```java
ForyJson json = ForyJson.builder().withFieldMode(true).build();
```

In field mode, getter/setter annotations are invalid. For ordinary properties, unknown members are
skipped and duplicate members use the last value. Polymorphic discriminator members are stricter
and must occur exactly once. JSON null is rejected for primitive targets. Most reference targets
return null, but a selected built-in or custom codec may define another result; declared Optional
targets return the corresponding empty Optional.

An ordinary class with a no-argument constructor runs it before readable properties are assigned,
so missing properties retain values established by field initializers or the constructor. On an
ordinary JVM, a class without such a constructor is allocated without running its constructors or
field initializers, and missing properties retain JVM zero or null values. Android cannot construct
an ordinary class without a usable no-argument constructor. GraalVM native image on JDK 25 and
later also requires one for most ordinary classes; the supported exception is a `Serializable`
class whose first non-serializable superclass is `Object`.

For portable construction, use a record, `JsonCreator`, or a no-argument constructor. Do not use an
ordinary constructor as a deserialization completion hook: property assignment follows a
no-argument constructor, while constructor-bypassing paths do not run it.

## Supported Java types

| Group              | Types and behavior                                                                                                                                                                                                                                                                     |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Scalars            | Primitive and boxed booleans/numbers/chars, strings and string builders, `BigInteger`, `BigDecimal`, Fory half-precision numbers, enums                                                                                                                                                |
| Containers         | Primitive/boxed/object arrays; collection, list, set, queue, deque, blocking, sorted, and navigable interfaces; map, sorted-map, navigable-map, and concurrent-map interfaces; supported concrete implementations; `EnumSet`; `EnumMap`; `Optional` variants; atomic values and arrays |
| Time               | `Date`, `Calendar`, `TimeZone`, Java time types, supported chronology dates, optional `java.sql.Date`, `Time`, and `Timestamp`                                                                                                                                                         |
| Other JDK          | `UUID`, `URI`, `File`, `Path`, `Locale`, `Charset`, `Currency`, `Pattern`, `BitSet`, `ByteBuffer`                                                                                                                                                                                      |
| Optional libraries | Guava `ImmutableList`, `ImmutableSet`, `ImmutableSortedSet`, `ImmutableMap`, `ImmutableBiMap`, `ImmutableSortedMap`, and `ImmutableIntArray` when Guava is present                                                                                                                     |
| Objects            | Mutable concrete classes, records, creator classes, `JsonObject`, `JsonArray`                                                                                                                                                                                                          |

Interfaces are reconstructed with appropriate standard mutable implementations. `ArrayBlockingQueue`,
`Arrays.asList` results, JDK immutable collections, empty/singleton/unmodifiable wrappers,
constructor-constrained implementations, and unlisted Guava immutable implementations cannot be
reconstructed. Guava remains optional.

Non-finite float/double values use quoted `"NaN"`, `"Infinity"`, and `"-Infinity"` tokens.

### Built-in representations

| Java type                                                                 | JSON representation                                                                                                 |
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Enum                                                                      | Constant name string                                                                                                |
| `Date`, `Calendar`, `java.sql.Date`, `Time`, `Timestamp`                  | Epoch-millisecond number                                                                                            |
| `TimeZone`                                                                | Time-zone ID string                                                                                                 |
| Java time and supported chronology date types                             | Standard textual string                                                                                             |
| `UUID`, `URI`, `File`, `Path`, `Locale`, `Charset`, `Currency`, `Pattern` | Type-specific text string; `File` and `Path` use path text, `Locale` uses a language tag, and `Pattern` loses flags |
| `BitSet`                                                                  | Array of signed `long` words                                                                                        |
| `ByteBuffer`                                                              | Array of signed byte values from position to limit                                                                  |
| Optional and atomic wrappers                                              | Contained scalar, array, or value directly                                                                          |

`Calendar` is reconstructed as a new `GregorianCalendar`, so its original subtype, time zone, and
other configuration are not retained. A null Optional reference and an empty Optional both write
JSON null; reading JSON null as a declared Optional type returns the corresponding empty Optional.

### Dynamic JSON trees

Reading `Object.class` produces natural JSON values:

| JSON                | Java                                       |
| ------------------- | ------------------------------------------ |
| Object              | `JsonObject`                               |
| Array               | `JsonArray`                                |
| String/boolean/null | `String`, `Boolean`, null                  |
| Integer             | `Long`, or `BigInteger` outside long range |
| Fraction/exponent   | `Double`                                   |

`JsonObject` preserves insertion order and `JsonArray` is mutable.

### Map keys

Declared keys support String, byte, short, int, long, their boxed types, and enums. `Object` keys
can write String, number, boolean, character, and enum values, but read back as strings. Null keys
are rejected.

## Builder configuration

| Method                       | Default                                      | Effect                                                 |
| ---------------------------- | -------------------------------------------- | ------------------------------------------------------ |
| `writeNullFields`            | `false`                                      | Default null-property inclusion                        |
| `withCodegen`                | `true`                                       | Generated object codecs                                |
| `withAsyncCompilation`       | `true`                                       | Asynchronous generated-code compilation                |
| `withFieldMode`              | `false`                                      | Field-only discovery when true                         |
| `withPropertyNamingStrategy` | `LOWER_CAMEL_CASE`                           | Naming of properties without explicit names            |
| `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)`                     | 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         |
| `withTypeChecker`            | None                                         | Application policy in addition to Fory's disallow list |

Depth, concurrency, and retained buffer limits must be positive. The cached-field-name limit applies
independently to each reader; zero disables the cache, and the setting does not limit accepted
input. The buffer setting does not limit output size. Builder changes after `build()` do not mutate
an existing runtime.

In a GraalVM native image, runtime code generation and asynchronous compilation are automatically
disabled. Every other builder option keeps the behavior described above.

## Annotations

Fory JSON provides `JsonProperty`, `JsonPropertyOrder`, `JsonIgnore`, `JsonAnyProperty`,
`JsonAnyGetter`, `JsonAnySetter`, `JsonCreator`, `JsonCodec`, `JsonValue`, `JsonRawValue`,
`JsonBase64`, `JsonUnwrapped`, and `JsonSubTypes` as mapping annotations under
`org.apache.fory.json.annotation`. `JsonType` is a separate build-time generation marker. They are
not Jackson, Gson, or Fory binary-protocol annotations.

```java
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.fory.json.PropertyNamingStrategy;
import org.apache.fory.json.annotation.JsonAnyGetter;
import org.apache.fory.json.annotation.JsonAnyProperty;
import org.apache.fory.json.annotation.JsonAnySetter;
import org.apache.fory.json.annotation.JsonBase64;
import org.apache.fory.json.annotation.JsonCodec;
import org.apache.fory.json.annotation.JsonCreator;
import org.apache.fory.json.annotation.JsonIgnore;
import org.apache.fory.json.annotation.JsonMixin;
import org.apache.fory.json.annotation.JsonMixinRemove;
import org.apache.fory.json.annotation.JsonProperty;
import org.apache.fory.json.annotation.JsonPropertyOrder;
import org.apache.fory.json.annotation.JsonRawValue;
import org.apache.fory.json.annotation.JsonSubTypes;
import org.apache.fory.json.annotation.JsonType;
import org.apache.fory.json.annotation.JsonValue;
import org.apache.fory.json.annotation.JsonUnwrapped;
```

`JsonType` asks the annotation processor to generate direct property and creator operations plus
the exact retention rules for an eligible concrete object model. A directly annotated
`JsonValue` Record also receives a companion so its value accessor and canonical constructor work
after Android desugaring. The same generated companion is used on the JVM, Android, and GraalVM
Native Image. The annotation is not inherited; a concrete subtype needs its own direct annotation
to receive a companion. See
[GraalVM Support](graalvm-support.md) and [Android Support](android-support.md) for setup.
A directly annotated model that uses the default object codec requires that generated companion;
the runtime reports a configuration error if the processor output is missing.

### Mixins

Use a Mixin to configure an existing class without changing its source:

```java
import org.apache.fory.json.ForyJson;
import org.apache.fory.json.annotation.JsonMixin;
import org.apache.fory.json.annotation.JsonProperty;
import org.apache.fory.json.annotation.JsonUnwrapped;

@JsonMixin(target = ThirdPartyUser.class)
abstract class ThirdPartyUserMixin {
  @JsonProperty("user_id")
  long id;

  @JsonUnwrapped(prefix = "address_")
  Address address;
}

ForyJson json = ForyJson.builder().registerMixin(ThirdPartyUserMixin.class).build();
```

The source must be a named abstract class or interface, must not be local or anonymous, must not
extend or implement another type, and is never instantiated. An annotated source field, method,
constructor, or parameter selects an existing target declaration by its Java signature. The source
cannot invent a Java field, method, constructor, generic type, subtype implementation, or executable
body. It may assign supported JSON roles such as property, creator, factory, subtype table, or value
representation to matching declarations that already exist on the target. Every Java type, access
operation, invocation, and runtime value still comes from the target.

Registration is exact-target only. A base-class registration does not change a subclass, and an
interface registration does not change an implementation. A subclass Mixin may select a member
that the subclass inherits, but the resulting annotation applies only while that exact subclass is
mapped.

All Fory JSON mapping annotations are supported: `JsonAnyGetter`, `JsonAnyProperty`,
`JsonAnySetter`, `JsonBase64`, `JsonCodec`, `JsonCreator`, `JsonIgnore`, `JsonProperty`,
`JsonPropertyOrder`, `JsonRawValue`, `JsonSubTypes`, `JsonUnwrapped`, and `JsonValue`. `JsonType`
cannot be added or removed because it controls build-time generation rather than the JSON schema.

A source annotation replaces the target annotation of the same type on the matched declaration.
The complete annotation is replaced, so omitted members use their declared defaults instead of
inheriting values from the target annotation. Other annotation types on that target declaration
remain effective.

Use `JsonMixinRemove` to make selected target annotations ineffective:

```java
import org.apache.fory.json.annotation.JsonMixin;
import org.apache.fory.json.annotation.JsonMixinRemove;
import org.apache.fory.json.annotation.JsonRawValue;

@JsonMixin(target = ThirdPartyMessage.class)
abstract class QuotedMessageMixin {
  @JsonMixinRemove(JsonRawValue.class)
  String body;
}
```

Removal affects only the matched declaration in the exact-target configuration. Removing
`JsonRawValue` restores ordinary quoted String output; removing `JsonBase64` restores the ordinary
`byte[]` representation; removing `JsonUnwrapped` restores a nested object property. Type-level
removal can mask inherited `JsonCodec` or `JsonPropertyOrder` declarations for the exact target.
Removing an absent annotation is harmless, but the selector must still match exactly one target
declaration. A source cannot both declare and remove the same annotation type on one declaration.

Only one source is enabled for an exact target in a built runtime. Registering a different source
for the same target replaces the earlier registration, while registering the same source again is
idempotent. `build()` snapshots the current last-registration-wins mapping; a later registration on
the builder does not change a previously built `ForyJson`. A source with no mapping annotations is
a no-op; registering it after another source for the same target clears the earlier overlay for
subsequent builds.

A `JsonCodec` supplied by a Mixin is the target's effective annotation and follows the ordinary
codec precedence below. In particular, an exact `registerCodec` registration wins over a type-level
Mixin codec, while a type-level Mixin codec wins over the built-in mapping for that target.

Records use their existing field, accessor, and canonical-constructor parameter declarations. A
Mixin does not introduce a separate record-component model. Use source selectors for those real
declarations and keep repeated annotations consistent as required by normal record property
mapping.

On Android and GraalVM Native Image, compile non-empty Mixin sources with the Fory annotation
processor so required generated operations and platform configuration are available. See
[Android Support](android-support.md) and [GraalVM Support](graalvm-support.md).

### `JsonProperty`

An annotation on a field, getter, or setter configures the complete merged logical property:

```java
@JsonProperty("user_id")
private long id;

@JsonProperty(include = JsonProperty.Include.ALWAYS)
private String displayName;

@JsonProperty(index = 10)
private String email;
```

Supported inclusion values are:

- `DEFAULT`: inherit `writeNullFields`;
- `ALWAYS`: include null;
- `NON_NULL`: omit null.

`index` controls relative serialization order. Indexed properties are written in ascending index
order before unindexed properties. Indexes must be non-negative, may contain gaps, and must be
unique among writable properties. `-1` means unspecified; lower values are invalid. An index on a
setter-only, creator-only, or write-ignored property is invalid.

Inclusion affects writing only. Identical repeated declarations are allowed; conflicting explicit
names, indexes, or non-default policies fail. Two properties cannot normalize to the same JSON
name. `JsonProperty` cannot be combined with an Any logical property or declared on a
`JsonAnySetter`. `NON_EMPTY`, aliases, and formatting are unsupported.

### `JsonPropertyOrder`

Use `JsonPropertyOrder` to combine a named prefix, property indexes, and final-name alphabetic
ordering:

```java
@JsonPropertyOrder(value = {"id", "display_name"}, alphabetic = true)
public final class User {
  @JsonProperty(index = 20)
  public String name;

  @JsonProperty(value = "display_name", index = 10)
  public String displayName;

  public long id;
  public int age;
  public String address;
}
```

The output order is `id`, `display_name`, `name`, `address`, then `age`:

```json
{ "id": 1, "display_name": "Alice", "name": "alice", "address": "x", "age": 30 }
```

The named prefix is written first. Remaining indexed properties follow in ascending index order.
When `alphabetic = true`, remaining unindexed properties are sorted by final JSON name; otherwise
they keep their existing relative order. Use `@JsonPropertyOrder(alphabetic = true)` when no named
prefix is needed. Alphabetic comparison uses Java's natural, case-sensitive String order and does
not depend on the locale.

Order entries match the final JSON name first and the Java logical property name second. This lets
`display_name` match an explicit `JsonProperty` name while an unannotated `displayName` can still be
addressed by either `display_name` under `SNAKE_CASE` or its Java name `displayName`.

The list may be empty only when `alphabetic` is true. Its entries must be non-empty, unique writable
properties; unknown and duplicate entries fail when the object metadata is built. A subclass
declaration replaces both settings from its superclass as a whole; declarations are not merged. If
the subclass has no declaration, the nearest superclass declaration is used and resolved against the
subclass properties. Interface declarations are not considered.

Property order affects serialization only. Deserialization remains name-based and accepts members
in any order. Subtype discriminators remain before user properties.

An unwrapped group also occupies one position, selected by the group's Java logical property name.
Its child members remain adjacent and retain the child's own order.

A write-enabled `JsonAnyProperty` or `JsonAnyGetter` participates as one position identified by its
Java logical property name:

```java
@JsonPropertyOrder({"id", "properties", "timestamp"})
public final class Event {
  public String id;

  @JsonAnyProperty
  public Map<String, Object> properties;

  public long timestamp;
}
```

The position emits every `properties` entry in Map iteration order between `id` and `timestamp`; it
does not emit a member named `properties`. Naming strategies do not transform the Any ordering
name. Input-only Any fields and `JsonAnySetter` have no write position. Dynamic keys cannot appear
in `JsonPropertyOrder`, and alphabetic ordering never sorts entries inside the Map.

### Naming strategy

```java
ForyJson json =
    ForyJson.builder()
        .withPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
        .build();
```

The default `LOWER_CAMEL_CASE` preserves the discovered Java logical property name. `SNAKE_CASE`
maps `userName` to `user_name`, `URLValue` to `url_value`, and `version2FA` to `version2_fa`.
Explicit `JsonProperty` names, parameter-local creator names, and subtype discriminator properties
bypass the strategy. Dynamic Any keys also bypass it.

### `JsonIgnore`

`JsonIgnore` is field-targeted and controls both directions of the complete logical property:

```java
@JsonIgnore(ignoreRead = false, ignoreWrite = true)
private String serverManagedValue;
```

Both flags default to true. Accessors cannot restore an ignored direction, and `JsonProperty`
cannot override it. Fory core's `Expose` has no effect in Fory JSON.

### `JsonValue`

Use `JsonValue` when one exact `String` member is the complete JSON representation of its owning
type. Fory writes it as an ordinary quoted and escaped JSON string instead of an object:

```java
import org.apache.fory.json.annotation.JsonCreator;
import org.apache.fory.json.annotation.JsonValue;

public final class UserId {
  private final String value;

  @JsonCreator
  public UserId(String value) {
    this.value = value;
  }

  @JsonValue
  public String value() {
    return value;
  }
}
```

The method may use any name but must be public, non-static, zero-argument, and return exactly
`String`. A field must be an eligible non-static instance field. Only one effective member is
allowed, and an unannotated override suppresses an inherited method annotation.

The annotation controls writing on its own. Reading requires a `JsonCreator` constructor or public
static factory with one exact `String` parameter, empty `JsonCreator.value()`, and no `JsonProperty`
on the parameter. This shape is inferred as the reverse String constructor; no creator mode is
needed. Existing property-based creator forms are unchanged. JSON null maps directly to Java null
without invoking the value member or creator.

### `JsonRawValue`

Use `JsonRawValue` on a fixed ordinary `String` property whose contents are already one complete
JSON value:

```java
import org.apache.fory.json.annotation.JsonRawValue;

public final class Response {
  public int status;

  @JsonRawValue
  public String body;
}
```

For `body = "{\"id\":1}"`, Fory emits the object directly at the `body` value position. It does not
quote, escape, parse, validate, or normalize the String. This is a trusted write-only escape hatch;
invalid or attacker-controlled content can make the entire output invalid or change its structure.
Java null follows the property's existing inclusion rule and is written as JSON null when included.

Reading is unchanged and still expects a JSON string. A raw object or array written through the
property cannot be read back into that `String`. The annotation does not apply to setters, creator
parameters, Any declarations, container elements, or Map values, and it cannot share an occurrence
with `JsonCodec`.
As an occurrence-local representation, it keeps the raw String shape even when the value type has
an exact builder-registered codec.

Neither annotation collects unknown sibling fields. Unknown fields are skipped unless an existing
`JsonAnyProperty` or `JsonAnyGetter`/`JsonAnySetter` mapping owns them. Combining `JsonValue` and
`JsonRawValue` on the same String member writes the owning object as a trusted raw root value, but
does not add a raw-fragment read contract.

### `JsonBase64`

Use `JsonBase64` on one exact `byte[]` field or getter to represent it as a quoted standard Base64
JSON string:

```java
import org.apache.fory.json.annotation.JsonBase64;

public final class Attachment {
  @JsonBase64
  public byte[] content;
}
```

Bytes `{1, 2, 3}` are written as `{"content":"AQID"}` and decoded back to the original array.
Encoding and decoding do not create an intermediate String. Null handling follows the property's
normal inclusion rule.

The annotation is not a type-use annotation and does not affect ordinary `byte[]` properties,
container elements, or Map values. It cannot share a logical property with `JsonRawValue`, an
occurrence `JsonCodec`, or an Any declaration. The equivalent explicit codec is
`@JsonCodec(Base64ByteArrayCodec.class)`.

### `JsonUnwrapped`

Use `JsonUnwrapped` when an object-valued property should keep its Java object boundary but place
its members in the containing JSON object:

```java
import org.apache.fory.json.annotation.JsonUnwrapped;

public final class Person {
  public int age;

  @JsonUnwrapped(prefix = "name_")
  public Name name;
}

public final class Name {
  public String first;
  public String last;
}
```

This writes `{"age":18,"name_first":"Ada","name_last":"Lovelace"}` instead of a
nested `name` object. `prefix` and `suffix` apply to every final child name after `JsonProperty` and
the configured naming strategy. Nested groups compose these transformations from the inside out.

A null child emits no members. During reading, the child is created only when at least one
flattened member is present. A missing group preserves a mutable parent's initialized value and
leaves a record or creator argument at its normal missing-property default. Partial input creates
the child and uses ordinary defaults for its other members.

Mutable classes, records, and `JsonCreator` classes are supported as parents and children. A
parameter-local creator parameter can define a read-only group; its required `JsonProperty` value
identifies the Java argument and is not a wrapper name. The containing parent may be parameterized,
but each unwrapped child and intermediate must be an exact raw, non-generic class using the standard
Fory object mapping.

The complete group occupies one position in parent serialization order. Position it with
`JsonProperty.index`, or list its Java logical property name in `JsonPropertyOrder`. Child ordering
is preserved inside the group. Input matches parent fixed properties first, flattened properties
second, and dynamic Any members last.

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

Use `JsonAnyProperty` to flatten a `Map<String, V>` field into the containing JSON object and store
otherwise unknown input members:

```java
public final class Event {
  public String id;

  @JsonAnyProperty
  public Map<String, Object> properties = new LinkedHashMap<>();
}
```

For `properties` containing `"source" -> "mobile"`, the result contains `"source":"mobile"`
beside `id`; no nested `properties` member is written. The field reads and writes by default.
`JsonIgnore` may select one direction, but it cannot disable both. During reading, Fory reuses an
existing Map or initializes a null non-final field on the first unknown member. A readable final
field on an ordinary mutable object must already contain a mutable Map. Records and property-list
`JsonCreator` types instead receive the accumulated Map through their construction argument.

Use `JsonAnyGetter` and `JsonAnySetter` for method-backed writing and reading:

```java
public final class Event {
  private final Map<String, Object> properties = new LinkedHashMap<>();

  @JsonAnyGetter
  public Map<String, Object> getProperties() {
    return properties;
  }

  @JsonAnySetter
  public void putProperty(String name, Object value) {
    properties.put(name, value);
  }
}
```

An any-getter must be a public instance method with no arguments and a `Map<String, V>` return type.
An any-setter must be a public instance method with signature `void method(String, V)`. Either may
be used independently. When paired, their resolved value types must match after primitive types are
boxed. A primitive any-setter value rejects JSON null. Any-setters are not supported on records or
types using `JsonCreator`.

A read-enabled `JsonAnyProperty` on a record component supplies that component from unknown input.
In property-list creator mode, a read-enabled Any field must correspond to one listed creator
argument; parameter-local creator mode cannot bind it. A write-only Any field or any-getter cannot
occupy a creator argument. If one claims a record component, that component receives its normal
Java default during reading.

An any-getter claims its complete Java logical property: both `getProperties()` and `properties()`
claim `properties`, so same-named ordinary fields and accessors are not mapped again as a fixed
member. Fory does not infer a differently named backing field; use `JsonIgnore` if that field must
not be mapped separately. An any-setter has no logical property name and does not claim a field.

The logical name is used only for grouping and `JsonPropertyOrder`; it is not a fixed JSON member.
An input member with that name is a dynamic entry rather than a nested aggregate. The same output
key remains valid unless another fixed property conflicts with it.

One effective type hierarchy may use either one Any field or up to one any-getter and one
any-setter. Field-backed and method-backed forms cannot be mixed, and method annotations are invalid
in field mode. An unannotated override disables an inherited method annotation. `JsonProperty` is
invalid on an any-setter and on every member claimed by an Any field or getter. A same-named field
cannot use `JsonIgnore` to suppress an any-getter's write direction, and its `ignoreRead` flag does
not disable a separate any-setter.

Dynamic keys are emitted unchanged in Map iteration order. A null Map emits nothing, while a null
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. 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`

The compact mode lists existing Java logical property names in parameter order and reuses their
normalized metadata:

```java
public final class User {
  public final long id;
  public final String name;

  @JsonCreator({"id", "name"})
  public User(long id, String name) {
    this.id = id;
    this.name = name;
  }
}
```

Parameter-local mode gives every parameter an explicit JSON name and permits creator-only inputs:

```java
@JsonCreator
public static User create(
    @JsonProperty("user_id") long id,
    @JsonProperty("display_name") String name) {
  return new User(id, name);
}
```

The modes cannot be mixed. Compact names must be non-empty and unique, their count must match the
parameter count, and compact parameters cannot also declare `JsonProperty`. Parameter-local mode
requires a non-empty, unique `JsonProperty` name on every parameter. The creator is the complete
read schema and setters do not run after it.

For a type with `JsonValue`, the empty form also accepts exactly one `String` parameter without
`JsonProperty` and reconstructs the owning value from its ordinary JSON string representation.

Exactly one creator is allowed. It must be public, have at least one parameter, and be neither
varargs nor generic. A factory is also static, declares the target class as its exact return type,
and returns a non-null value whose runtime class is exactly the target. Missing references use null,
missing primitives use zero, duplicate members use the last value, and explicit primitive null
fails. Records cannot declare a property-based `JsonCreator`; a record with `JsonValue` may annotate
its one-String canonical constructor for the value form.

### `JsonSubTypes`

`JsonSubTypes` defines a complete finite table on an interface or abstract base. Each entry has a
case-sensitive logical name and exactly one Java source: a class literal or trusted binary
`className`. JSON never supplies class names or expands the table.

Default property inclusion:

```java
@JsonSubTypes(
    property = "kind",
    value = {
      @JsonSubTypes.Type(value = Circle.class, name = "circle"),
      @JsonSubTypes.Type(
          className = "com.example.shape.Rectangle",
          name = "rectangle")
    })
public interface Shape {}
```

```json
{ "kind": "circle", "radius": 2 }
```

The discriminator is emitted first but may appear at any direct input member position. It must
occur exactly once, contain a known String name, and not collide with a subtype property.

Wrapper object:

```java
@JsonSubTypes(
    inclusion = JsonSubTypes.Inclusion.WRAPPER_OBJECT,
    value = {@JsonSubTypes.Type(value = Circle.class, name = "circle")})
public interface Shape {}
```

```json
{ "circle": { "radius": 2 } }
```

Wrapper array:

```java
@JsonSubTypes(
    inclusion = JsonSubTypes.Inclusion.WRAPPER_ARRAY,
    value = {@JsonSubTypes.Type(value = Circle.class, name = "circle")})
public interface Shape {}
```

```json
["circle", { "radius": 2 }]
```

| Inclusion        | `property`             | Value rule                          |
| ---------------- | ---------------------- | ----------------------------------- |
| `PROPERTY`       | Required and non-empty | Ordinary subtype object members     |
| `WRAPPER_OBJECT` | Must be empty          | Complete subtype value              |
| `WRAPPER_ARRAY`  | Must be empty          | Complete subtype value as element 1 |

Wrapper inclusions support exact custom subtype codecs. Logical names and resolved concrete,
assignable classes must each be unique. Only exact listed runtime classes are accepted; listing a
parent does not admit descendants. The annotation is read from the declared base itself and is not
inherited from another annotated base. Null is plain JSON null unless codec precedence selects a
custom complete-value codec for the declared base, replacing the annotation. Readers accept only
the configured shape, so changing inclusion is a wire-format change. At GraalVM native-image
runtime, annotate the base with `JsonType` and use class literals instead of `className`. Listed
class-literal subtypes are registered automatically.

## Custom codecs

`JsonValueCodec<T>` reads and writes one complete JSON value, including null, through Fory's
concrete String/UTF-8 writers and Latin-1/UTF-16/UTF-8 readers. It is a direct streaming-value SPI,
not a JSON abstract syntax tree (AST) codec. It never handles Map keys; `MapKeyCodec` owns JSON
object member names.

For an application codec with the same semantics in every representation, extend
`AbstractJsonValueCodec<T>` and implement the JSON shape once:

```java
import java.math.BigDecimal;
import org.apache.fory.json.codec.AbstractJsonValueCodec;
import org.apache.fory.json.reader.JsonReader;
import org.apache.fory.json.writer.JsonWriter;

public final class MoneyCodec extends AbstractJsonValueCodec<Money> {
  @Override
  public void write(JsonWriter writer, Money value) {
    if (value == null) {
      writer.writeNull();
    } else {
      writer.writeBigDecimal(value.amount);
    }
  }

  @Override
  public Money read(JsonReader reader) {
    return reader.tryReadNullToken() ? null : new Money(reader.readBigDecimal());
  }
}

final class Money {
  final BigDecimal amount;

  Money(BigDecimal amount) {
    this.amount = amount;
  }
}
```

`AbstractJsonValueCodec` adds one virtual method call per operation. For a
performance-sensitive codec, or when behavior depends on a concrete reader or writer, implement
`JsonValueCodec<T>` directly and provide all five representation-specific methods.

Register it once:

```java
import org.apache.fory.json.ForyJson;

ForyJson json =
    ForyJson.builder()
        .registerCodec(Money.class, new MoneyCodec())
        .build();
```

The parent property still controls its name, ignore direction, and null inclusion before the codec
runs. An emitted property and every array, collection, map-value, Optional, or atomic-reference
position delegate the complete value, including null. The registered codec instance is shared
concurrently and must be thread-safe. A custom codec on a subtype is compatible with wrapper
inclusion, not inline property inclusion. A codec on the base replaces its `JsonSubTypes`
annotation.

### Selecting codecs with `JsonCodec`

Use `@JsonCodec` on a class, record, enum, or interface to declare its default complete-value
codec. The positional form is shorthand for `value`:

```java
@JsonCodec(MoneyCodec.class)
public final class Money {}

@JsonCodec(AccountCodec.class)
public interface Account {}

public final class RetailAccount implements Account {}
```

Type declarations are inherited through both superclasses and interfaces. The most-specific
declaration wins. Unrelated declarations using the same codec are consistent; unrelated
declarations using different codecs fail instead of depending on reflection order.

On a field or effective ordinary getter, `value` replaces the complete property value. The same
annotation is supported on an effective setter value parameter, a `JsonCreator` constructor or
factory parameter, and a record component through Java's field, accessor, and constructor-parameter
propagation:

```java
public final class Invoice {
  @JsonCodec(MoneyCodec.class)
  public Money total;
  private Money tax;
  private Money discount;

  @JsonCodec(MoneyCodec.class)
  public Money getTax() {
    return tax;
  }

  public void setDiscount(@JsonCodec(MoneyCodec.class) Money discount) {
    this.discount = discount;
  }

  @JsonCreator
  public Invoice(@JsonProperty("total") @JsonCodec(MoneyCodec.class) Money total) {
    this.total = total;
  }
}
```

Use a child member when the standard container should remain in control and only its direct child
needs a custom codec:

```java
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceArray;

public final class InvoiceGroup {
  @JsonCodec(elementCodec = MoneyCodec.class)
  public List<Money> items;

  @JsonCodec(elementCodec = MoneyCodec.class)
  public Money[] itemArray;

  @JsonCodec(elementCodec = MoneyCodec.class)
  public AtomicReferenceArray<Money> atomicItems;

  @JsonCodec(contentCodec = MoneyCodec.class)
  public Optional<Money> optional;

  @JsonCodec(contentCodec = MoneyCodec.class)
  public AtomicReference<Money> current;

  @JsonCodec(keyCodec = CurrencyKeyCodec.class, valueCodec = MoneyCodec.class)
  public Map<Currency, Money> byCurrency;
}
```

The child members have these meanings:

| Member         | Supported current value                           | Direct child handled by the codec |
| -------------- | ------------------------------------------------- | --------------------------------- |
| `elementCodec` | `Collection<E>`, `E[]`, `AtomicReferenceArray<E>` | `E`                               |
| `contentCodec` | `Optional<T>`, `AtomicReference<T>`               | `T`                               |
| `keyCodec`     | `Map<K, V>`                                       | JSON member name for `K`          |
| `valueCodec`   | `Map<K, V>`                                       | direct `V` value                  |

A custom Map-key codec converts between the declared key and a JSON member name:

```java
import java.util.Locale;
import org.apache.fory.json.codec.MapKeyCodec;

public final class CurrencyKeyCodec implements MapKeyCodec {
  @Override
  public String toName(Object key) {
    return ((Currency) key).name().toLowerCase(Locale.ROOT);
  }

  @Override
  public Object fromName(String name) {
    return Currency.valueOf(name.toUpperCase(Locale.ROOT));
  }
}
```

Code that used the removed type-use form should move the codec to the owning declaration:

```java
// Before
List<@JsonCodec(MoneyCodec.class) Money> items;

// Now
@JsonCodec(elementCodec = MoneyCodec.class)
List<Money> items;
```

Use `contentCodec` for an `Optional` or `AtomicReference`, `valueCodec` for a Map value, and
`elementCodec` for an array or `AtomicReferenceArray` element.

`Iterable<E>` values that are not `Collection<E>` do not support `elementCodec`. Use `value` when a
complete codec should own such a value.

Child configuration is intentionally one level deep. For `List<List<Money>>`, `elementCodec`
handles each complete `List<Money>`. For `Money[][]`, it handles each `Money[]`. To customize a
deeper descendant, implement a codec for the complete current value and select it with `value`.

`value` is mutually exclusive with every child member because it already owns the complete current
value. An empty annotation, an unsupported child member, or an outer complete codec combined with
a child member fails during model construction. A configured direct child must resolve to a
concrete type; raw containers, direct wildcards, and unresolved direct type variables are rejected.

`JsonAnyProperty` and `JsonAnyGetter` flatten their Map into the enclosing object. Configure their
dynamic values with `valueCodec`:

```java
@JsonAnyProperty
@JsonCodec(valueCodec = MoneyCodec.class)
public Map<String, Money> extra;
```

The first `JsonAnySetter` parameter is the String property name. Its second parameter may use
`@JsonCodec(value = ...)` or another configuration valid for that parameter's own shape.

### Codec precedence and repeated declarations

Fory resolves each current value in this order:

| Priority | Source                                            |
| -------: | ------------------------------------------------- |
|        1 | Current property or parameter `JsonCodec`         |
|        2 | Exact `registerCodec` registration                |
|        3 | Exact-target type `JsonCodec` after Mixin overlay |
|        4 | Inherited-frontier type `JsonCodec` declaration   |
|        5 | Built-in or default JSON mapping                  |

One logical property may expose the annotation from its field, getter, setter parameter, creator
parameter, or record propagation. Repeated configurations must be identical; Fory does not merge
partial configurations from different declarations. An unannotated effective override suppresses
an inherited method annotation.

A child member replaces only that direct child. Unconfigured Map siblings continue through the
normal precedence. If an exact registration or type declaration supplies a complete codec for the
outer container, a property child member is unreachable and therefore rejected.

Map keys are JSON object member names and use `MapKeyCodec`, not `JsonValueCodec`. A custom key
codec class follows the same construction rules as a value codec. Null Map keys are rejected, and
decoded keys must match the declared key type.

### Codec construction and platform support

An annotation codec class must be public, concrete, top-level or static nested, and have a public
no-argument constructor. One instance is shared by all annotated sites and concurrent operations of
the built `ForyJson`, so it must be thread-safe. Use `registerCodec(Target.class, instance)` when a
complete-value codec needs configuration.

In a named Java module, export or open the codec package to `org.apache.fory.json`. When an inherited
type-declaration codec is used for a more specific target, every decoded value must be null or
assignable to that target.

The annotation has the same FIELD, METHOD, and PARAMETER behavior on the JVM, Android, and GraalVM
Native Image. Ordinary Android classes may omit `JsonType` and provide equivalent exact rules.
Android-desugared Records, including `JsonValue` Records, require processor-generated operations
from either a direct `JsonType` declaration or a compiled exact `JsonMixin` pair. GraalVM object
models follow the build-time workflow in
[GraalVM Support](graalvm-support.md).

## Type validation and untrusted input

Fory JSON always applies its fixed disallow list. Add an application policy with:

```java
ForyJson json =
    ForyJson.builder()
        .withTypeChecker(
            (className, context) ->
                className.startsWith("com.example.model.")
                    || className.equals("java.util.List")
                    || className.equals("java.util.Map"))
        .build();
```

Allow every application model and non-built-in container type that the declared schema uses. The
checker applies while application types are prepared for serialization and parsing and must be
thread-safe. Built-in scalars normally skip the custom checker, but selecting an application codec
for a built-in target makes that target subject to the checker. Custom codecs cannot bypass the
fixed disallow list.

`withClassLoader` fixes subtype `className` resolution. Otherwise `build()` snapshots the thread
context class loader and falls back to the Fory JSON loader.

`maxDepth` is not an input-size or memory quota. Enforce request size, timeout, and resource limits
at the transport boundary. `Class`, `URL`, `InetAddress`, and `InetSocketAddress` are unsupported by
default. URL and arbitrary unsupported Number/CharSequence subclasses require exact custom codecs.

## Limits and unsupported features

- No shared-reference identity or circular-reference protocol. Use Fory binary when needed.
- No open polymorphism, JSON class-name IDs, subtype discovery, or runtime subtype-table extension.
- No InputStream parser, incremental `OutputStream` writer on the `ForyJson` root API, or
  pretty-print configuration.
- No Jackson/Gson annotation compatibility.
- No aliases, views, filters, injection, managed/back references, object identity annotations, root
  wrapping, or format annotations.
- Fory core's `Expose` is ignored.

Circular graphs eventually fail `maxDepth`; they are not reconstructed.

## Errors and troubleshooting

| Symptom                            | Action                                                                                          |
| ---------------------------------- | ----------------------------------------------------------------------------------------------- |
| `ForyJsonException`                | Check JSON grammar, target type, mapping support, depth, trailing content, or output cause      |
| `InsecureException`                | Check Fory's disallow list and the configured type checker                                      |
| Builder `IllegalArgumentException` | Check the configured depth, concurrency, retained-buffer, and cached-field-name limits          |
| Declared write fails               | Remove wildcard/type variables and pass an assignable value; primitive declarations reject null |
| Immutable value is empty           | Use a record, valid creator, or custom codec                                                    |
| `JsonValue` read fails             | Add one plain `String` creator, or register an exact custom codec                               |
| Raw JSON output is invalid         | Supply one trusted, complete JSON value to the `JsonRawValue` property                          |
| Ordinary object cannot be created  | Add a usable no-argument constructor, use a record or creator, or register a codec              |
| Ordinary accessor annotation fails | Use an eligible public JavaBean accessor and disable field mode                                 |
| Any annotation fails               | Use one field form or one valid method pair with resolved `Map<String, V>` types                |
| Codec annotation fails             | Resolve same-node or hierarchy conflicts, hidden nested overrides, or codec constructor access  |
| Subtype fails                      | Write with the declared base, list the exact runtime class, and use the configured wire shape   |
| Collection fails                   | Target a supported interface/common implementation or register a codec                          |

Creator failures other than `Error` are wrapped with their original cause. User codec code may
still throw its own runtime exceptions.

## Related Java guides

- [Java serialization overview](index.md)
- [Native binary serialization](native-serialization.md)
- [Xlang binary serialization](xlang-serialization.md)
- [Java configuration](configuration.md)
- [Troubleshooting](troubleshooting.md)
