跳到主要内容
版本:dev

Static Generated Serializers

Static generated serializers are Java serializers generated by javac during your application build. They are useful when runtime code generation is disabled or unavailable.

Use them when:

  • you run on Android.
  • you run an ordinary JVM with ForyBuilder#withCodegen(false) and want generated serializers.
  • your Android model classes use Fory type-use annotations such as @Ref, @UInt8Type, or @Float16Type.

For GraalVM native images, follow GraalVM Support instead.

Install The Annotation Processor

Add fory-annotation-processor to the annotation processor path of the module that compiles your serializable classes:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.apache.fory</groupId>
<artifactId>fory-annotation-processor</artifactId>
<version>${fory.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>

The generated serializers depend on fory-core at runtime. Applications opt in by adding the annotation processor; fory-core does not depend on it.

Annotate Classes

Annotate each serializable class with @ForyStruct:

import org.apache.fory.annotation.ForyStruct;

@ForyStruct
public class Order {
public long id;
public String note;

public Order() {}
}

The processor generates serializer classes in the same Java package as the annotated class. For Order, the generated classes are:

  • Order__ForySerializer__ for cross-language mode.
  • Order__ForyNativeSerializer__ for Java native mode.

For a static nested type such as Outer.Inner, the generated top-level classes are Outer$Inner__ForySerializer__ and Outer$Inner__ForyNativeSerializer__.

Field Debug Tracing

Add @ForyDebug next to @ForyStruct when you need generated serializers to include field-level debug tracing hooks. The generated code prints those traces only when ENABLE_FORY_DEBUG_OUTPUT=1.

import org.apache.fory.annotation.ForyDebug;
import org.apache.fory.annotation.ForyStruct;

@ForyStruct
@ForyDebug
public class DebugOrder {
public long id;
public String note;

public DebugOrder() {}
}

Runtime Use

Fory uses static generated serializers when they are available on:

  • Android.
  • ordinary JVMs with ForyBuilder#withCodegen(false).
  • compatible-mode reads when the target struct has a generated serializer.

On an ordinary JVM with codegen=true, Fory continues to prefer runtime-generated serializers.

Field Access Rules

Generated serializers must be able to access serialized fields or their accessors at compile time.

  • Public, protected, and package-private fields can be accessed directly when Java package access allows same-package generated serializers to use them.
  • Private serialized fields must have accessible non-private getter and setter methods, or be excluded with transient or Fory @Ignore.
  • Public, protected, and package-private getter/setter methods are accepted when they are accessible from the generated serializer package.
  • Final fields are not supported for normal mutable classes because generated read and copy methods must assign fields. Use records for constructor-based immutable values.

For records, generated serializers use public record accessors and construct values through the canonical record constructor. Ignored record components are skipped by serialization and copy, and their constructor arguments use Java default values during generated read/copy.

Type-Use Annotations On Android

On Android, static generated serializers are required when a class uses Fory type-use annotations on nested types:

import java.util.List;
import org.apache.fory.annotation.ForyStruct;
import org.apache.fory.annotation.UInt8Type;

@ForyStruct
public class ImageBlock {
public List<@UInt8Type Integer> pixels;
}

Without the generated serializer metadata, Android may not expose enough nested type information for Fory to preserve annotations such as @Ref, @Int8Type, @UInt8Type, @Float16Type, or @BFloat16Type.

Compatible Reads

Static generated serializers support both normal serialization and compatible-mode reads. Compatible reads match remote fields to local fields, skip fields that no longer exist locally, and keep Java default values for fields that are missing from the remote payload.