This is an automated email from the ASF dual-hosted git repository.

chaokunyang pushed a commit to branch release_fory_1.2.0
in repository https://gitbox.apache.org/repos/asf/fory-site.git

commit aa9674b72c9e53a1cce38e425d495bcf2ea397e8
Author: 慕白 <[email protected]>
AuthorDate: Tue Jun 16 21:40:20 2026 +0800

    Add Fory 1.2.0 release blog
---
 blog/2026-06-16-fory_1_2_0_release.md | 378 ++++++++++++++++++++++++++++++++++
 1 file changed, 378 insertions(+)

diff --git a/blog/2026-06-16-fory_1_2_0_release.md 
b/blog/2026-06-16-fory_1_2_0_release.md
new file mode 100644
index 0000000000..42e976344a
--- /dev/null
+++ b/blog/2026-06-16-fory_1_2_0_release.md
@@ -0,0 +1,378 @@
+---
+slug: fory_1_2_0_release
+title: Fory v1.2.0 Released
+authors: [chaokunyang]
+tags: [fory, java, kotlin, scala, android, python, rust, c++, go, c#, swift, 
dart, compiler]
+---
+
+The Apache Fory team is pleased to announce the 1.2.0 release. This release 
includes [38 PRs](https://github.com/apache/fory/compare/v1.1.0...v1.2.0) from 
9 distinct contributors and continues to improve the cross-language runtime 
across supported languages. See the 
[Install](https://fory.apache.org/docs/start/install) page to get the libraries 
for your platform.
+
+## 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 implementation for the core runtime so 
applications
+can run on JDK 25+ without resolving `sun.misc.Unsafe` from Fory's active class
+graph.
+
+The implementation keeps the fast JDK 8-24 paths for older runtimes, but JDK 
25+
+loads replacement classes from the versioned jar area. Those replacements move
+field access and memory-buffer primitives to supported JVM mechanisms such as
+`VarHandle`, `MethodHandle`, arrays, and `ByteBuffer`. Constructor-bypassing
+allocation is also handled explicitly: on JDK 25+ classes that previously
+depended on Unsafe allocation should provide an accessible no-arg constructor,
+use record construction, or register a custom serializer.
+
+This is an important compatibility milestone for Java users because the runtime
+no longer depends on a terminally deprecated Unsafe API path when the 
application
+runs on Java 25 and later.
+
+## 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, Python, Java, and C++, but 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. You can still make the setting explicit:
+
+```java
+Fory fory = Fory.builder()
+    .withXlang(true)
+    .withCompatible(true)
+    .build();
+```
+
+```python
+import pyfory
+
+fory = pyfory.Fory(xlang=True, compatible=True)
+native_fory = pyfory.Fory(xlang=False, compatible=True)
+```
+
+Rust example:
+
+```rust
+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");
+```
+
+Python example:
+
+```python
+from dataclasses import dataclass
+import pyfory
+
+@dataclass
+class MetricV1:
+    value: pyfory.Int64
+
+@dataclass
+class MetricV2:
+    value: str
+
+writer = pyfory.Fory(xlang=True, compatible=True)
+writer.register(MetricV1, name="example.Metric")
+
+reader = pyfory.Fory(xlang=True, compatible=True)
+reader.register(MetricV2, name="example.Metric")
+
+data = writer.dumps(MetricV1(42))
+assert reader.loads(data).value == "42"
+```
+
+Java example:
+
+```java
+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");
+```
+
+C++ example:
+
+```cpp
+#include <cassert>
+#include <string>
+#include "fory/serialization/fory.h"
+
+using namespace fory::serialization;
+
+struct MetricV1 {
+  int64_t value;
+};
+FORY_STRUCT(MetricV1, value);
+
+struct MetricV2 {
+  std::string value;
+};
+FORY_STRUCT(MetricV2, value);
+
+auto writer = Fory::builder().xlang(true).compatible(true).build();
+auto reader = Fory::builder().xlang(true).compatible(true).build();
+
+writer.register_struct<MetricV1>("example", "Metric");
+reader.register_struct<MetricV2>("example", "Metric");
+
+auto bytes = writer.serialize(MetricV1{42}).value();
+auto value = reader.deserialize<MetricV2>(bytes).value();
+assert(value.value == "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.
+
+The examples below use this shared schema:
+
+```protobuf
+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:
+
+```bash
+foryc service.fdl --rust_out=./generated/rust --grpc
+```
+
+```rust
+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?;
+```
+
+Go generation emits grpc-go interfaces and a Fory-backed `CodecV2`:
+
+```bash
+foryc service.fdl --go_out=./generated/go --grpc
+```
+
+```go
+server := grpc.NewServer(
+    grpc.ForceServerCodecV2(greeter.CodecV2{}),
+)
+greeter.RegisterGreeterServer(server, greeterService{})
+
+client := greeter.NewGreeterClient(conn)
+reply, err := client.SayHello(ctx, &greeter.HelloRequest{Name: "Fory"})
+```
+
+JavaScript generation supports both Node.js gRPC and browser gRPC-Web:
+
+```bash
+foryc service.fdl --javascript_out=./generated/javascript --grpc --grpc-web
+```
+
+```ts
+import * as grpc from "@grpc/grpc-js";
+import { addGreeterService, createGreeterClient } from "./service_grpc";
+import { createGreeterWebPromiseClient } from "./service_grpc_web";
+
+addGreeterService(server, greeterHandlers);
+
+const nodeClient = createGreeterClient(
+  "localhost:50051",
+  grpc.credentials.createInsecure(),
+);
+nodeClient.sayHello({ name: "Fory" }, callback);
+
+const webClient = createGreeterWebPromiseClient("https://api.example.com";);
+const reply = await webClient.sayHello({ name: "Fory" });
+```
+
+Browser gRPC-Web follows gRPC-Web transport limits: unary and server-streaming
+methods are supported, while client-streaming and bidirectional streaming 
remain
+Node.js/native gRPC shapes.
+
+Kotlin generation emits grpc-kotlin coroutine companions:
+
+```bash
+foryc service.fdl --kotlin_out=./generated/kotlin --grpc
+```
+
+```kotlin
+class GreeterService : GreeterGrpcKt.GreeterCoroutineImplBase() {
+  override suspend fun sayHello(request: HelloRequest): HelloReply =
+    HelloReply(reply = "Hello, ${request.name}")
+}
+
+val server = ServerBuilder
+  .forPort(50051)
+  .addService(GreeterService())
+  .build()
+  .start()
+
+val stub = GreeterGrpcKt.GreeterCoroutineStub(channel)
+val reply = stub.sayHello(HelloRequest(name = "Fory"))
+```
+
+Scala generation emits Scala 3 grpc-java companions with Scala-friendly client
+handles:
+
+```bash
+foryc service.fdl --scala_out=./generated/scala --grpc
+```
+
+```scala
+final class GreeterService extends GreeterGrpc.GreeterImplBase {
+  override def sayHello(request: HelloRequest): HelloReply =
+    HelloReply(s"Hello, ${request.name}")
+}
+
+val server = ServerBuilder
+  .forPort(50051)
+  .addService(new GreeterService)
+  .build()
+  .start()
+
+val client = GreeterGrpc.newClient(channel)
+val reply = Await.result(client.sayHello(HelloRequest("Fory")).asFuture, 
30.seconds)
+```
+
+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
+
+* feat(java): add java9/16 module-info support by @chaokunyang in 
https://github.com/apache/fory/pull/3721
+* refactor(format): inline custom-codec dispatch in row codecs by 
@stevenschlansker in https://github.com/apache/fory/pull/3716
+* perf(format): cache compact row layout per nested slot by @stevenschlansker 
in https://github.com/apache/fory/pull/3717
+* feat(java): remove sun.misc.Unsafe for jdk25 by @chaokunyang in 
https://github.com/apache/fory/pull/3702
+* feat(rust): support thread safe `Arc<dyn Any + Send + Sync>` type by 
@chaokunyang in https://github.com/apache/fory/pull/3736
+* refactor(rust): refactor sync send type by @chaokunyang in 
https://github.com/apache/fory/pull/3737
+* feat(xlang): refine register by name api by @chaokunyang in 
https://github.com/apache/fory/pull/3739
+* feat(xlang): support compatible scalar read conversions by @chaokunyang in 
https://github.com/apache/fory/pull/3740
+* feat: default compatible mode for native serialization by @chaokunyang in 
https://github.com/apache/fory/pull/3742
+* perf: optimize compatible mode read performance by @chaokunyang in 
https://github.com/apache/fory/pull/3743
+* feat(compiler): handle Rust identifier escaping and name collisions by 
@BaldDemian in https://github.com/apache/fory/pull/3744
+* feat(go): implement grpc stub generation by @ayush00git in 
https://github.com/apache/fory/pull/3698
+* refactor(compiler): generate C++ unordered map for Fory map by @BaldDemian 
in https://github.com/apache/fory/pull/3745
+* feat(compiler): handle nested container ref pointer options in C++ compiler 
correctly by @BaldDemian in https://github.com/apache/fory/pull/3735
+* feat: add more read checks by @chaokunyang in 
https://github.com/apache/fory/pull/3748
+* feat(compiler): support Rust gRPC code generation by @BaldDemian in 
https://github.com/apache/fory/pull/3738
+* feat(cpp): support struct property accessors by @chaokunyang in 
https://github.com/apache/fory/pull/3751
+* feat(python): make scalar wire markers typing-friendly by @chaokunyang in 
https://github.com/apache/fory/pull/3756
+* feat(kotlin): add kotlin grpc support by @chaokunyang in 
https://github.com/apache/fory/pull/3757
+* feat(rust): make fory-derive generated code use exported api in fory rust 
lib by @chaokunyang in https://github.com/apache/fory/pull/3759
+* feat(scala): add generated grpc service support for scala by @chaokunyang in 
https://github.com/apache/fory/pull/3762
+* feat(csharp): add generated grpc support for C# by @chaokunyang in 
https://github.com/apache/fory/pull/3761
+* feat(javascript): add javascript gRPC support for nodejs/browser by 
@chaokunyang in https://github.com/apache/fory/pull/3760
+
+## Bug Fix
+
+* fix(go): return nil serializer on getTypeInfo err by @ayush00git in 
https://github.com/apache/fory/pull/3719
+* fix(benchmarks): uses outdated google-java-format, upgrade spotless by 
@stevenschlansker in https://github.com/apache/fory/pull/3722
+* fix(format): pass row body size, not full payload size, to BinaryRow.pointTo 
by @stevenschlansker in https://github.com/apache/fory/pull/3715
+* fix(java): fix deflater memory leak by @MNTMDEV in 
https://github.com/apache/fory/pull/3726
+* fix(compiler): handle nested container ref pointer options in Rust compiler 
correctly by @BaldDemian in https://github.com/apache/fory/pull/3731
+* fix(java): ignore non-Scala/Lombok-style default helper methods by @mandrean 
in https://github.com/apache/fory/pull/3733
+* fix(c++): std::unordered_map cannot be used in struct. (#3727) by 
@ruoruoniao in https://github.com/apache/fory/pull/3728
+* fix(grpc): fix rust/go grpc support by @chaokunyang in 
https://github.com/apache/fory/pull/3753
+* fix(cpp): align unsigned struct default encoding by @chaokunyang in 
https://github.com/apache/fory/pull/3754
+
+## Other Improvements
+
+* chore(deps): fix vulnerable dependencies by @chaokunyang in 
https://github.com/apache/fory/pull/3741
+* chore: Bump MessagePack from 2.5.187 to 2.5.301 by @dependabot[bot] in 
https://github.com/apache/fory/pull/3750
+* chore(deps): bump Go gRPC test dependencies by @chaokunyang in 
https://github.com/apache/fory/pull/3763
+
+## New Contributors
+
+* @MNTMDEV made their first contribution in 
https://github.com/apache/fory/pull/3726
+* @ruoruoniao made their first contribution in 
https://github.com/apache/fory/pull/3728
+
+**Full Changelog**: https://github.com/apache/fory/compare/v1.1.0...v1.2.0


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to