Skip to content

fix(deps): update fory to v1.3.0#43

Open
rossdanderson wants to merge 1 commit into
mainfrom
renovate/fory
Open

fix(deps): update fory to v1.3.0#43
rossdanderson wants to merge 1 commit into
mainfrom
renovate/fory

Conversation

@rossdanderson

@rossdanderson rossdanderson commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

This PR contains the following updates:

Package Change Age Confidence
org.apache.fory:fory-kotlin (source) 1.1.01.3.0 age confidence
org.apache.fory:fory-core 1.1.01.3.0 age confidence

Release Notes

apache/fory (org.apache.fory:fory-core)

v1.3.0

Highlights

  • Python gRPC code generation now defaults to the grpc.aio AsyncIO API, while synchronous grpcio output remains available through --grpc-python-mode=sync.
  • Dart joins the generated gRPC service surface: foryc --dart_out=... --grpc now emits package:grpc clients, service bases, method descriptors, and Fory-backed payload serialization.
  • Compiler gRPC documentation was refined across languages, including clearer guidance for generated service dependencies and transport behavior.
  • Runtime hardening continued with remote schema metadata limits and Java aligned-varint/type-checker fixes.

Python Async gRPC Mode

Python gRPC generation now targets AsyncIO by default. Generated companions use
grpc.aio: servicer bases expose async def methods, stubs are used with
grpc.aio.Channel instances, and streaming RPCs use async iterables. This keeps
the generated code aligned with modern Python async services while preserving
the same Fory-backed request and response encoding used by the existing gRPC
support.

Generate the default async companion with:

foryc service.fdl --python_out=./generated/python --grpc

For a simple unary service, the generated async server shape is:

import asyncio

import grpc.aio

import demo_greeter
import demo_greeter_grpc

class Greeter(demo_greeter_grpc.GreeterServicer):
    async def say_hello(self, request, context):
        return demo_greeter.HelloReply(reply=f"Hello, {request.name}")

async def serve():
    server = grpc.aio.server()
    demo_greeter_grpc.add_servicer(Greeter(), server)
    server.add_insecure_port("[::]:50051")
    await server.start()
    await server.wait_for_termination()

asyncio.run(serve())

Clients use a grpc.aio channel and await generated stub methods:

import grpc
import grpc.aio

import demo_greeter
import demo_greeter_grpc

credentials = grpc.ssl_channel_credentials()
async with grpc.aio.secure_channel("api.example.com:443", credentials) as channel:
    stub = demo_greeter_grpc.GreeterStub(channel)
    reply = await stub.say_hello(demo_greeter.HelloRequest(name="Fory"))

Existing synchronous applications can still request sync companions explicitly:

foryc service.fdl --python_out=./generated/python --grpc --grpc-python-mode=sync

In sync mode the generated public names and <module>_grpc.py filename stay the
same, but applications use grpc.server(...), standard grpc.Channel
instances, and regular def servicer methods.

Dart gRPC Code Generation

Fory 1.3.0 adds Dart gRPC service generation for schemas with service
definitions. Service definitions can come from Fory IDL, protobuf IDL, or
FlatBuffers rpc_service definitions. The generated code uses normal
grpc-dart APIs for clients, service bases, method descriptors, call options,
deadlines, cancellations, metadata, and status codes, while each request and
response object is serialized with Fory instead of protobuf message bytes.

Add grpc and build_runner alongside the Fory package in the Dart
application:

dependencies:
  fory: ^1.3.0
  grpc: ^4.0.0

dev_dependencies:
  build_runner: ^2.4.0

Generate Dart models and the gRPC companion with:

foryc service.fdl --dart_out=./lib/generated --grpc
dart run build_runner build --delete-conflicting-outputs

For a demo.greeter package, the generator emits the model file, the
build_runner serializer part, and a <stem>_grpc.dart companion with
GreeterServiceBase and GreeterClient. The generated client and service base
install the schema's Fory module automatically on first use, so service
implementations do not need a separate manual registration step for the
generated message types.

A unary Dart server uses grpc-dart's Server and the generated service base:

import 'dart:io';

import 'package:grpc/grpc.dart';
import 'demo/greeter/greeter.dart';
import 'demo/greeter/greeter_grpc.dart';

class GreeterService extends GreeterServiceBase {
  @&#8203;override
  Future<HelloReply> sayHello(ServiceCall call, HelloRequest request) async {
    return HelloReply()..reply = 'Hello, ${request.name}';
  }
}

Future<void> main() async {
  final server = Server.create(services: [GreeterService()]);
  await server.serve(address: InternetAddress.loopbackIPv4, port: 50051);
}

Generated Dart clients use standard ClientChannel values and return the
grpc-dart call types:

import 'package:grpc/grpc.dart';
import 'demo/greeter/greeter.dart';
import 'demo/greeter/greeter_grpc.dart';

final channel = ClientChannel(
  'localhost',
  port: 50051,
  options: const ChannelOptions(credentials: ChannelCredentials.insecure()),
);
final client = GreeterClient(channel);

final reply = await client.sayHello(HelloRequest()..name = 'Fory');
await channel.shutdown();

Dart generation covers unary, server-streaming, client-streaming, and
bidirectional streaming RPC shapes following grpc-dart conventions.

Features

Bug Fix

Other Improvements

New Contributors

Full Changelog: apache/fory@v1.2.0...v1.3.0

v1.2.0

Highlights

  • Expanded generated gRPC support across Go, Rust, Kotlin, Scala, C#, and JavaScript, including Node.js and browser gRPC-Web support for JavaScript.
  • Improved cross-language compatibility with refined register-by-name APIs, compatible scalar read conversions, and default compatible mode for native serialization.
  • Strengthened Java platform support by adding Java 9/16 module-info generation and removing sun.misc.Unsafe usage for JDK 25.
  • Improved runtime safety and robustness with additional read checks, deflater leak fixes, and safer serializer/type-info error handling.
  • Optimized compatible-mode and row-format performance through faster compatible reads, compact row layout caching, and inlined custom-codec dispatch.
  • Enhanced compiler output quality across Rust, C++, and service generation with better identifier escaping, name-collision handling, nested container reference handling, and map code generation.

Java 25+ Without sun.misc.Unsafe

JDK 25 continues the platform shift away from sun.misc.Unsafe. Fory 1.2.0
adds a Java 25 multi-release runtime path so applications can run on JDK 25+
without resolving sun.misc.Unsafe from Fory's active class graph.

Older JDKs keep the existing fast paths. On JDK 25+, Fory uses replacement
classes backed by supported JVM mechanisms such as VarHandle, MethodHandle,
arrays, and ByteBuffer. Classes that previously depended on constructor
bypassing should provide an accessible no-arg constructor, use records, or
register a custom serializer.

Compatible Scalar Field Reads

Compatible mode already allows readers and writers to add, remove, and reorder
fields. Fory 1.2.0 extends that model to selected scalar type changes: when a
matched top-level field changes between boolean, string, numeric, and decimal
types, the reader can deserialize the value if the conversion is lossless.

Examples include reading "123" as an integer field, reading 1 or 0 as a
boolean field, reading booleans as 1/0, reading numbers or decimals as
canonical strings, and widening or narrowing numeric values only when no range
or precision is lost. Invalid strings, out-of-range values, lossy float/integer
conversions, and reference-tracked scalar type changes fail during
deserialization. The conversion applies to matched compatible fields, not to
root values or collection elements.

The examples below show Rust and Java using an int64 writer field and a
String reader field. The same compatible scalar field conversion is supported
across Fory's compatible-mode runtimes: Java, Python, Rust, C++, Go, C#, Swift,
Dart, JavaScript/TypeScript, Kotlin, and Scala. Compatible mode is enabled by
default in the Java and Python runtimes for both xlang and native serialization.

Rust example:

use fory::{Fory, ForyStruct};

#[derive(ForyStruct)]
struct MetricV1 {
    value: i64,
}

#[derive(ForyStruct)]
struct MetricV2 {
    value: String,
}

let mut writer = Fory::builder().xlang(true).compatible(true).build();
writer.register_by_name::<MetricV1>("example.Metric")?;

let mut reader = Fory::builder().xlang(true).compatible(true).build();
reader.register_by_name::<MetricV2>("example.Metric")?;

let bytes = writer.serialize(&MetricV1 { value: 42 })?;
let value: MetricV2 = reader.deserialize(&bytes)?;
assert_eq!(value.value, "42");

Java example:

public class MetricV1 {
  public long value;
}

public class MetricV2 {
  public String value;
}

Fory writer = Fory.builder().withXlang(true).withCompatible(true).build();
writer.register(MetricV1.class, "example", "Metric");

Fory reader = Fory.builder().withXlang(true).withCompatible(true).build();
reader.register(MetricV2.class, "example", "Metric");

MetricV1 source = new MetricV1();
source.value = 42L;
byte[] bytes = writer.serialize(source);
MetricV2 value = reader.deserialize(bytes, MetricV2.class);
assert value.value.equals("42");

The same rule works in the other direction, for example reading a String
field value such as "42" as int64, when the string uses Fory's strict
finite decimal grammar and the target range can represent the value exactly.

Generated gRPC Support

Fory 1.2.0 expands compiler-generated gRPC service companions. The generated
services use standard gRPC transports, channels, deadlines, metadata,
interceptors, status codes, and streaming shapes, while request and response
objects are encoded with Fory instead of protobuf message bytes. Use this mode
when both sides of the RPC are generated from the same Fory IDL, protobuf IDL,
or FlatBuffers IDL and you want gRPC operational semantics with Fory payload
encoding.

Generated gRPC support now covers Java, Python, Go, Rust, C#, Scala, Kotlin,
and JavaScript/TypeScript. JavaScript includes Node.js gRPC support and browser
gRPC-Web client generation. Only Rust and Java snippets are shown below; the
other supported languages provide the same Fory-backed service companion model
without duplicating code here.

The examples below use this shared schema:

package demo.greeter;

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string reply = 1;
}

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply);
}

Rust generation emits tonic-based service API and binding modules:

use demo_greeter::{HelloReply, HelloRequest};
use demo_greeter_service::Greeter;
use demo_greeter_service_grpc::greeter_client::GreeterClient;
use demo_greeter_service_grpc::greeter_server::GreeterServer;

tonic::transport::Server::builder()
    .add_service(GreeterServer::new(MyGreeter::default()))
    .serve(addr)
    .await?;

let mut client = GreeterClient::connect("http://[::1]:50051").await?;
let reply = client.say_hello(HelloRequest { name: "Fory".into() }).await?;

Java generation emits grpc-java service bases, stubs, and Fory codecs:

final class GreeterService extends GreeterGrpc.GreeterImplBase {
  @&#8203;Override
  public void sayHello(
      HelloRequest request, StreamObserver<HelloReply> responseObserver) {
    HelloReply reply = new HelloReply();
    reply.setReply("Hello, " + request.getName());
    responseObserver.onNext(reply);
    responseObserver.onCompleted();
  }
}

Server server = ServerBuilder.forPort(50051)
    .addService(new GreeterService())
    .build()
    .start();

GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel);
HelloRequest request = new HelloRequest();
request.setName("Fory");
HelloReply reply = stub.sayHello(request);

The generated gRPC companions intentionally do not make gRPC a hard dependency
of the core Fory language packages. Applications add the transport libraries
they use: grpc-java for Java and Scala, grpcio for Python, grpc-go for Go,
tonic/bytes for Rust, .NET gRPC packages for C#, @grpc/grpc-js or
grpc-web for JavaScript, and grpc-java/grpc-kotlin for Kotlin.

Features

Bug Fix

Other Improvements

New Contributors

Full Changelog: apache/fory@v1.1.0...v1.2.0


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about these updates again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Mend Renovate.

@rossdanderson rossdanderson changed the title fix(deps): update fory to v1.2.0 fix(deps): update fory to v1.3.0 Jun 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants