[Java] Public, stable token-level JSON reader/writer API (and a standalone reader/writer artifact)

Đang mở
#4,164 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@dstepanov đang làm issue này rồi.

Từ ngày 14/10/2026.

  • #4180 của @dstepanov — đang mở

Đánh giá

Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức phù hợp với người mới
35/100
Loại issue
Tính năng
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
java
Lĩnh vực
api, backend

Hướng nghiên cứu

Start by reading the Utf8JsonReader and Utf8JsonWriter APIs, JsonConfig, and the related builder and resolver code mentioned in the issue. Define which token methods are public and stable, how callers construct readers and writers, and whether a standalone artifact is in scope; the issue proposes several alternatives and does not settle those design choices. Done means framework integrations can use a documented token API without a split-package workaround, with the artifact boundary and packed-token support clarified.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Feature Request

Make the token-level Utf8JsonReader / Utf8JsonWriter a supported public API, usable without going through ForyJson's object mapping, and consider publishing them as a separate, lightweight artifact.

Is your feature request related to a problem? Please describe

I'm evaluating fory-json (1.7.6) as a JSON backend for Micronaut Serialization. Micronaut Serialization has its own compile-time generated (de)serializers and only needs a fast streaming tokenizer/generator underneath, the same way it uses jackson-core today. So it drives Utf8JsonReader / Utf8JsonWriter directly and does not use ForyJson's codecs.

This works well. The module passes our full serialization TCK on the JVM and in a GraalVM native image. Benchmarks on our standard user-bean model (JDK 25) show:

serialize (ops/µs) deserialize (µs/op)
Micronaut Serialization on jackson-core 0.523 3.053
Micronaut Serialization on fory-json reader/writer 1.254 2.347

Most of the gain comes from the reader/writer internals: word-at-a-time scanning, number parsing/formatting, and especially the packed field-name tokens. We precompute "name": / ,"name": / {"name": as long words per property and use writeRawValue(long, long, long, long, int, int, int), writeObjectStartWithRawValue(long, long, int) and tryReadNextFieldNameToken0 / tryReadNextFieldNameToken8, the same way Fory's generated codecs do.

However, the integration currently relies on things that don't look like public API:

  1. Constructing a reader/writer needs a JsonConfig, but there is no public way to obtain one. JsonConfig has no public constructor or builder, and ForyJson.config() is package-private. We currently need a class placed in the org.apache.fory.json package (split package) just to call ForyJson.builder().build().config(). That won't work on the module path, and it's fragile.
  2. JsonTypeResolver / JsonSharedRegistry are required constructor arguments, even though a token-level user never registers or resolves types.
  3. It's unclear which reader/writer methods are stable. Several neighbouring methods are marked @Internal (e.g. Utf8JsonWriter.getBuffer()/setBuffer(), Utf8JsonReader.tryConsumeNextComma(), methods on JsonTypeResolver), and the packed-token methods above look like they are primarily meant for generated code.
Describe the solution you'd like
  • A public way to create readers/writers, e.g. a public JsonConfig builder, or factory methods such as ForyJson.newUtf8Reader() / newUtf8Writer() (or standalone Utf8JsonReader.create(options)). They shouldn't need a type resolver when used at token level.
  • A documented, stable token-level API on Utf8JsonReader / Utf8JsonWriter, including:
    • the structural/scalar methods (peekToken, expect, consume, consumeCommaOrEndObject/Array, read*, skipValue, finish, write*, writeComma, writeFieldName);
    • the packed field-name token methods (writeRawValue(long...), writeObjectStartWithRawValue, tryReadNextFieldNameToken0/8), ideally with a public helper that builds the packed token values for a given name, so callers don't have to re-implement the packing and escaping rules.
  • A separate artifact containing only the reader/writer (e.g. fory-json-stream or fory-json-core), without the object-mapping layer, codegen/Janino, annotations or codec registry. For framework integrations that bring their own mapping layer, this would:
    • keep the dependency footprint small, comparable to jackson-core vs jackson-databind (today the full fory-json plus fory-core is pulled in, roughly 3.9 MB);
    • simplify GraalVM native-image setup, since there are no runtime code generation paths;
    • give a clear boundary for what is public and stable.
Describe alternatives you've considered
  • Using ForyJson directly: not an option for us, because the mapping is done by our own generated code, which has to honour our annotations, views, subtype handling and so on.
  • Keeping the split-package workaround: it works on the classpath, but it's brittle across releases and incompatible with JPMS.
Additional context
  • Related: #3961 (InputStream-based reading). An InputStream/chunked input mode on the reader would let us avoid buffering the whole request body.
  • Happy to share the integration code or help with a PR if this direction makes sense.
Ngôn ngữ chính
Java
Star
4.6k
Fork
470
Merge trung bình
9 giờ 28 phút
Pull request đã merge (30 ngày)
33

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của apache/fory

Tất cả issue của apache/fory

Issue tương tự

Thêm issue về Java

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.