This is an automated email from the ASF dual-hosted git repository.
zrlw pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git
The following commit(s) were added to refs/heads/master by this push:
new ef82834f Add serialization extension for Apache Fory #15470 (#656)
ef82834f is described below
commit ef82834f6dbc7815595c722482fa0af097cbd8ae
Author: laokou <[email protected]>
AuthorDate: Thu Jun 19 13:16:45 2025 +0800
Add serialization extension for Apache Fory #15470 (#656)
---
README.md | 1 +
README_CN.md | 1 +
dubbo-extensions-dependencies-bom/pom.xml | 6 +
.../dubbo-serialization-fory/pom.xml | 60 +++++++
.../fory/dubbo/BaseForySerialization.java | 69 ++++++++
.../serialize/fory/dubbo/ForyCheckerListener.java | 93 ++++++++++
.../fory/dubbo/ForyCompatibleSerialization.java | 64 +++++++
.../serialize/fory/dubbo/ForyObjectInput.java | 126 +++++++++++++
.../serialize/fory/dubbo/ForyObjectOutput.java | 111 ++++++++++++
.../fory/dubbo/ForyScopeModelInitializer.java | 38 ++++
.../serialize/fory/dubbo/ForySerialization.java | 63 +++++++
...org.apache.dubbo.common.serialize.Serialization | 2 +
...rg.apache.dubbo.rpc.model.ScopeModelInitializer | 2 +
.../common/serialize/fory/ForyObjectInputTest.java | 108 ++++++++++++
.../serialize/fory/ForyObjectOutputTest.java | 196 +++++++++++++++++++++
.../serialize/fory/ForySerializationTest.java | 67 +++++++
dubbo-serialization-extensions/pom.xml | 1 +
17 files changed, 1008 insertions(+)
diff --git a/README.md b/README.md
index c0405150..04ed3cd5 100644
--- a/README.md
+++ b/README.md
@@ -89,6 +89,7 @@ The available extensions are as follows:
-
[dubbo-serialization-fastjson](dubbo-serialization-extensions/dubbo-serialization-fastjson)
-
[dubbo-serialization-fst](dubbo-serialization-extensions/dubbo-serialization-fst)
-
[dubbo-serialization-fury](dubbo-serialization-extensions/dubbo-serialization-fury)
+ -
[dubbo-serialization-fory](dubbo-serialization-extensions/dubbo-serialization-fory)
-
[dubbo-serialization-gson](dubbo-serialization-extensions/dubbo-serialization-gson)
-
[dubbo-serialization-jackson](dubbo-serialization-extensions/dubbo-serialization-jackson)
-
[dubbo-serialization-jdk](dubbo-serialization-extensions/dubbo-serialization-jdk)
diff --git a/README_CN.md b/README_CN.md
index 77b111ba..06b4cbdb 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -88,6 +88,7 @@ dubbo-spi-extensions的目的是提供开放的、社区驱动的、可重用的
-
[dubbo-serialization-fastjson](dubbo-serialization-extensions/dubbo-serialization-fastjson)
-
[dubbo-serialization-fst](dubbo-serialization-extensions/dubbo-serialization-fst)
-
[dubbo-serialization-fury](dubbo-serialization-extensions/dubbo-serialization-fury)
+ -
[dubbo-serialization-fory](dubbo-serialization-extensions/dubbo-serialization-fory)
-
[dubbo-serialization-gson](dubbo-serialization-extensions/dubbo-serialization-gson)
-
[dubbo-serialization-jackson](dubbo-serialization-extensions/dubbo-serialization-jackson)
-
[dubbo-serialization-kryo](dubbo-serialization-extensions/dubbo-serialization-kryo)
diff --git a/dubbo-extensions-dependencies-bom/pom.xml
b/dubbo-extensions-dependencies-bom/pom.xml
index 3cf02d8d..99876be0 100644
--- a/dubbo-extensions-dependencies-bom/pom.xml
+++ b/dubbo-extensions-dependencies-bom/pom.xml
@@ -112,6 +112,7 @@
<fastjson_version>1.2.83_noneautotype</fastjson_version>
<fst_version>2.57</fst_version>
<apache.fury_version>0.10.2</apache.fury_version>
+ <apache.fory_version>0.11.0</apache.fory_version>
<jackson_version>2.18.3</jackson_version>
<gson_version>2.13.0</gson_version>
<kryo_version>5.6.2</kryo_version>
@@ -318,6 +319,11 @@
<artifactId>fury-core</artifactId>
<version>${apache.fury_version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.fory</groupId>
+ <artifactId>fory-core</artifactId>
+ <version>${apache.fory_version}</version>
+ </dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
diff --git a/dubbo-serialization-extensions/dubbo-serialization-fory/pom.xml
b/dubbo-serialization-extensions/dubbo-serialization-fory/pom.xml
new file mode 100644
index 00000000..8821260a
--- /dev/null
+++ b/dubbo-serialization-extensions/dubbo-serialization-fory/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.dubbo.extensions</groupId>
+ <artifactId>dubbo-serialization-extensions</artifactId>
+ <version>${revision}</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>dubbo-serialization-fory</artifactId>
+ <packaging>jar</packaging>
+ <name>${project.artifactId}</name>
+ <version>${revision}</version>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-serialization-api</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.fory</groupId>
+ <artifactId>fory-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.dubbo.extensions</groupId>
+ <artifactId>dubbo-serialization-test</artifactId>
+ <version>${revision}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git
a/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/BaseForySerialization.java
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/BaseForySerialization.java
new file mode 100644
index 00000000..cb5660b8
--- /dev/null
+++
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/BaseForySerialization.java
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+package org.apache.dubbo.common.serialize.fory.dubbo;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.serialize.ObjectInput;
+import org.apache.dubbo.common.serialize.ObjectOutput;
+import org.apache.dubbo.common.serialize.Serialization;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+
+import org.apache.fory.Fory;
+import org.apache.fory.collection.Tuple2;
+import org.apache.fory.memory.MemoryBuffer;
+import org.apache.fory.util.LoaderBinding;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Optional;
+/**
+ * Fory serialization framework integration with dubbo.
+ *
+ * @author chaokunyang
+ */
+public abstract class BaseForySerialization implements Serialization {
+ protected abstract Tuple2<LoaderBinding, MemoryBuffer> getFory();
+
+ public ObjectOutput serialize(URL url, OutputStream output) throws
IOException {
+ Tuple2<LoaderBinding, MemoryBuffer> tuple2 = getFory();
+ tuple2.f0.setClassLoader(Thread.currentThread().getContextClassLoader());
+ Fory fory = tuple2.f0.get();
+ ForyCheckerListener checkerListener = getCheckerListener(url);
+ fory.getClassResolver().setClassChecker(checkerListener.getChecker());
+ fory.getClassResolver().setSerializerFactory(checkerListener);
+ return new ForyObjectOutput(fory, tuple2.f1, output);
+ }
+
+ public ObjectInput deserialize(URL url, InputStream input) throws
IOException {
+ Tuple2<LoaderBinding, MemoryBuffer> tuple2 = getFory();
+ tuple2.f0.setClassLoader(Thread.currentThread().getContextClassLoader());
+ Fory fory = tuple2.f0.get();
+ ForyCheckerListener checkerListener = getCheckerListener(url);
+ fory.getClassResolver().setClassChecker(checkerListener.getChecker());
+ return new ForyObjectInput(fory, tuple2.f1, input);
+ }
+
+ private static ForyCheckerListener getCheckerListener(URL url) {
+ return Optional.ofNullable(url)
+ .map(URL::getOrDefaultFrameworkModel)
+ .orElseGet(FrameworkModel::defaultModel)
+ .getBeanFactory()
+ .getBean(ForyCheckerListener.class);
+ }
+}
diff --git
a/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForyCheckerListener.java
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForyCheckerListener.java
new file mode 100644
index 00000000..cda3d92c
--- /dev/null
+++
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForyCheckerListener.java
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+package org.apache.dubbo.common.serialize.fory.dubbo;
+
+import org.apache.dubbo.common.utils.AllowClassNotifyListener;
+import org.apache.dubbo.common.utils.SerializeCheckStatus;
+import org.apache.dubbo.common.utils.SerializeSecurityManager;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+
+import org.apache.fory.Fory;
+import org.apache.fory.exception.InsecureException;
+import org.apache.fory.resolver.AllowListChecker;
+import org.apache.fory.serializer.Serializer;
+import org.apache.fory.serializer.SerializerFactory;
+
+import java.io.Serializable;
+import java.util.Set;
+
+@SuppressWarnings("rawtypes")
+public class ForyCheckerListener implements AllowClassNotifyListener,
SerializerFactory {
+ private final AllowListChecker checker;
+ private volatile boolean checkSerializable;
+
+ public ForyCheckerListener(FrameworkModel frameworkModel) {
+ checker = new AllowListChecker();
+ SerializeSecurityManager securityManager =
frameworkModel.getBeanFactory().getOrRegisterBean(SerializeSecurityManager.class);
+ securityManager.registerListener(this);
+ }
+
+ @Override
+ public void notifyPrefix(Set<String> allowedList, Set<String>
disAllowedList) {
+ for (String prefix : allowedList) {
+ checker.allowClass(prefix + "*");
+ }
+ for (String prefix : disAllowedList) {
+ checker.disallowClass(prefix + "*");
+ }
+ }
+
+ @Override
+ public void notifyCheckStatus(SerializeCheckStatus status) {
+ switch (status) {
+ case DISABLE:
+ checker.setCheckLevel(AllowListChecker.CheckLevel.DISABLE);
+ return;
+ case WARN:
+ checker.setCheckLevel(AllowListChecker.CheckLevel.WARN);
+ return;
+ case STRICT:
+ checker.setCheckLevel(AllowListChecker.CheckLevel.STRICT);
+ return;
+ default:
+ throw new UnsupportedOperationException("Unsupported check level " +
status);
+ }
+ }
+
+ @Override
+ public void notifyCheckSerializable(boolean checkSerializable) {
+ this.checkSerializable = checkSerializable;
+ }
+
+ public AllowListChecker getChecker() {
+ return checker;
+ }
+
+ public boolean isCheckSerializable() {
+ return checkSerializable;
+ }
+
+ @Override
+ public Serializer createSerializer(Fory fory, Class<?> cls) {
+ if (checkSerializable && !Serializable.class.isAssignableFrom(cls)) {
+ throw new InsecureException(String.format("%s is not Serializable",
cls));
+ }
+ return null;
+ }
+
+}
diff --git
a/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForyCompatibleSerialization.java
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForyCompatibleSerialization.java
new file mode 100644
index 00000000..1d4cdf6e
--- /dev/null
+++
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForyCompatibleSerialization.java
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+package org.apache.dubbo.common.serialize.fory.dubbo;
+
+
+import org.apache.fory.Fory;
+import org.apache.fory.collection.Tuple2;
+import org.apache.fory.config.CompatibleMode;
+import org.apache.fory.memory.MemoryBuffer;
+import org.apache.fory.memory.MemoryUtils;
+import org.apache.fory.util.LoaderBinding;
+
+/**
+ * Fory serialization for dubbo. This integration support type
forward/backward compatibility.
+ *
+ * @author chaokunyang
+ */
+public class ForyCompatibleSerialization extends BaseForySerialization {
+ public static final byte FORY_SERIALIZATION_ID = 29;
+ private static final ThreadLocal<Tuple2<LoaderBinding, MemoryBuffer>>
foryFactory =
+ ThreadLocal.withInitial(
+ () -> {
+ LoaderBinding binding =
+ new LoaderBinding(
+ classLoader ->
+ Fory.builder()
+ .withRefTracking(true)
+ .withStringCompressed(true)
+ .requireClassRegistration(false)
+ .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ .withClassLoader(classLoader)
+ .build());
+ MemoryBuffer buffer = MemoryUtils.buffer(32);
+ return Tuple2.of(binding, buffer);
+ });
+
+ public byte getContentTypeId() {
+ return FORY_SERIALIZATION_ID;
+ }
+
+ public String getContentType() {
+ return "fory/compatible";
+ }
+
+ @Override
+ protected Tuple2<LoaderBinding, MemoryBuffer> getFory() {
+ return foryFactory.get();
+ }
+}
diff --git
a/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForyObjectInput.java
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForyObjectInput.java
new file mode 100644
index 00000000..3da7c609
--- /dev/null
+++
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForyObjectInput.java
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+package org.apache.dubbo.common.serialize.fory.dubbo;
+
+import org.apache.dubbo.common.serialize.ObjectInput;
+
+import org.apache.fory.Fory;
+import org.apache.fory.io.BlockedStreamUtils;
+import org.apache.fory.memory.MemoryBuffer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Type;
+
+@SuppressWarnings("unchecked")
+public class ForyObjectInput implements ObjectInput {
+ private final Fory fory;
+ private final MemoryBuffer buffer;
+ private final InputStream input;
+
+ public ForyObjectInput(Fory fory, MemoryBuffer buffer, InputStream input) {
+ this.fory = fory;
+ this.buffer = buffer;
+ this.input = input;
+ }
+
+ @Override
+ public Object readObject() {
+ return BlockedStreamUtils.deserialize(fory, input);
+ }
+
+ @Override
+ public <T> T readObject(Class<T> cls) {
+ return (T) readObject();
+ }
+
+ @Override
+ public <T> T readObject(Class<T> cls, Type type) {
+ return (T) readObject();
+ }
+
+ @Override
+ public boolean readBool() throws IOException {
+ readBytes(buffer.getHeapMemory(), 1);
+ return buffer.getBoolean(0);
+ }
+
+ @Override
+ public byte readByte() throws IOException {
+ readBytes(buffer.getHeapMemory(), 1);
+ return buffer.getByte(0);
+ }
+
+ @Override
+ public short readShort() throws IOException {
+ readBytes(buffer.getHeapMemory(), 2);
+ return buffer.getInt16(0);
+ }
+
+ @Override
+ public int readInt() throws IOException {
+ readBytes(buffer.getHeapMemory(), 4);
+ return buffer.getInt32(0);
+ }
+
+ @Override
+ public long readLong() throws IOException {
+ readBytes(buffer.getHeapMemory(), 8);
+ return buffer.getInt64(0);
+ }
+
+ @Override
+ public float readFloat() throws IOException {
+ readBytes(buffer.getHeapMemory(), 4);
+ return buffer.getFloat32(0);
+ }
+
+ @Override
+ public double readDouble() throws IOException {
+ readBytes(buffer.getHeapMemory(), 8);
+ return buffer.getFloat64(0);
+ }
+
+ @Override
+ public String readUTF() throws IOException {
+ int size = readInt();
+ buffer.readerIndex(0);
+ buffer.ensure(size);
+ readBytes(buffer.getHeapMemory(), size);
+ if (buffer.readBoolean()) {
+ return fory.readJavaString(buffer);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public byte[] readBytes() throws IOException {
+ int size = readInt();
+ byte[] bytes = new byte[size];
+ readBytes(bytes, size);
+ return bytes;
+ }
+
+ private void readBytes(byte[] bytes, int size) throws IOException {
+ int off = 0;
+ while (off != size) {
+ off += input.read(bytes, off, size - off);
+ }
+ }
+}
diff --git
a/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForyObjectOutput.java
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForyObjectOutput.java
new file mode 100644
index 00000000..1ae62bc6
--- /dev/null
+++
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForyObjectOutput.java
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+package org.apache.dubbo.common.serialize.fory.dubbo;
+
+import org.apache.dubbo.common.serialize.ObjectOutput;
+
+import org.apache.fory.Fory;
+import org.apache.fory.io.BlockedStreamUtils;
+import org.apache.fory.memory.MemoryBuffer;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Fory implementation for {@link ObjectOutput}.
+ *
+ * @author chaokunyang
+ */
+public class ForyObjectOutput implements ObjectOutput {
+ private final Fory fory;
+ private final MemoryBuffer buffer;
+ private final OutputStream output;
+
+ public ForyObjectOutput(Fory fory, MemoryBuffer buffer, OutputStream output)
{
+ this.fory = fory;
+ this.buffer = buffer;
+ this.output = output;
+ }
+
+ public void writeObject(Object obj) {
+ BlockedStreamUtils.serialize(fory, output, obj);
+ }
+
+ public void writeBool(boolean v) throws IOException {
+ buffer.putBoolean(0, v);
+ output.write(buffer.getHeapMemory(), 0, 1);
+ }
+
+ public void writeByte(byte v) throws IOException {
+ buffer.putByte(0, v);
+ output.write(buffer.getHeapMemory(), 0, 1);
+ }
+
+ public void writeShort(short v) throws IOException {
+ buffer.putInt16(0, v);
+ output.write(buffer.getHeapMemory(), 0, 2);
+ }
+
+ public void writeInt(int v) throws IOException {
+ buffer.putInt32(0, v);
+ output.write(buffer.getHeapMemory(), 0, 4);
+ }
+
+ public void writeLong(long v) throws IOException {
+ buffer.putInt64(0, v);
+ output.write(buffer.getHeapMemory(), 0, 8);
+ }
+
+ public void writeFloat(float v) throws IOException {
+ buffer.putFloat32(0, v);
+ output.write(buffer.getHeapMemory(), 0, 4);
+ }
+
+ public void writeDouble(double v) throws IOException {
+ buffer.putFloat64(0, v);
+ output.write(buffer.getHeapMemory(), 0, 8);
+ }
+
+ public void writeUTF(String v) throws IOException {
+ // avoid `writeInt` overwrite sting data.
+ buffer.writerIndex(4);
+ if (v != null) {
+ buffer.writeBoolean(true);
+ fory.writeJavaString(buffer, v);
+ } else {
+ buffer.writeBoolean(false);
+ }
+ int size = buffer.writerIndex() - 4;
+ writeInt(size);
+ output.write(buffer.getHeapMemory(), 4, size);
+ }
+
+ public void writeBytes(byte[] v) throws IOException {
+ writeInt(v.length);
+ output.write(v);
+ }
+
+ public void writeBytes(byte[] v, int off, int len) throws IOException {
+ writeInt(len);
+ output.write(v, off, len);
+ }
+
+ public void flushBuffer() throws IOException {
+ output.flush();
+ }
+}
diff --git
a/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForyScopeModelInitializer.java
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForyScopeModelInitializer.java
new file mode 100644
index 00000000..c73f0473
--- /dev/null
+++
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForyScopeModelInitializer.java
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+package org.apache.dubbo.common.serialize.fory.dubbo;
+
+import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+import org.apache.dubbo.rpc.model.ModuleModel;
+import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+
+public class ForyScopeModelInitializer implements ScopeModelInitializer {
+ @Override
+ public void initializeFrameworkModel(FrameworkModel frameworkModel) {
+ ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
+ beanFactory.registerBean(ForyCheckerListener.class);
+ }
+
+ @Override
+ public void initializeApplicationModel(ApplicationModel applicationModel) {}
+
+ @Override
+ public void initializeModuleModel(ModuleModel moduleModel) {}
+}
diff --git
a/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForySerialization.java
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForySerialization.java
new file mode 100644
index 00000000..2914efb5
--- /dev/null
+++
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/java/org/apache/dubbo/common/serialize/fory/dubbo/ForySerialization.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+package org.apache.dubbo.common.serialize.fory.dubbo;
+
+
+import org.apache.fory.Fory;
+import org.apache.fory.collection.Tuple2;
+import org.apache.fory.memory.MemoryBuffer;
+import org.apache.fory.memory.MemoryUtils;
+import org.apache.fory.util.LoaderBinding;
+
+/**
+ * Fory serialization for dubbo. This integration doesn't allow type
inconsistency between
+ * serialization and deserialization peer.
+ *
+ * @author chaokunyang
+ */
+public class ForySerialization extends BaseForySerialization {
+ public static final byte FORY_SERIALIZATION_ID = 28;
+ private static final ThreadLocal<Tuple2<LoaderBinding, MemoryBuffer>>
foryFactory =
+ ThreadLocal.withInitial(
+ () -> {
+ LoaderBinding binding =
+ new LoaderBinding(
+ classLoader ->
+ Fory.builder()
+ .withRefTracking(true)
+ .withStringCompressed(true)
+ .requireClassRegistration(false)
+ .withClassLoader(classLoader)
+ .build());
+ MemoryBuffer buffer = MemoryUtils.buffer(32);
+ return Tuple2.of(binding, buffer);
+ });
+
+ public byte getContentTypeId() {
+ return FORY_SERIALIZATION_ID;
+ }
+
+ public String getContentType() {
+ return "fory/consistent";
+ }
+
+ @Override
+ protected Tuple2<LoaderBinding, MemoryBuffer> getFory() {
+ return foryFactory.get();
+ }
+}
diff --git
a/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
new file mode 100644
index 00000000..0b3aa520
--- /dev/null
+++
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
@@ -0,0 +1,2 @@
+fory=org.apache.dubbo.common.serialize.fory.dubbo.ForySerialization
+fory-compatible=org.apache.dubbo.common.serialize.fory.dubbo.ForyCompatibleSerialization
diff --git
a/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer
new file mode 100644
index 00000000..bc187a50
--- /dev/null
+++
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer
@@ -0,0 +1,2 @@
+fory=org.apache.dubbo.common.serialize.fory.dubbo.ForyScopeModelInitializer
+fory-compatible=org.apache.dubbo.common.serialize.fory.dubbo.ForyScopeModelInitializer
diff --git
a/dubbo-serialization-extensions/dubbo-serialization-fory/src/test/java/org/apache/dubbo/common/serialize/fory/ForyObjectInputTest.java
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/test/java/org/apache/dubbo/common/serialize/fory/ForyObjectInputTest.java
new file mode 100644
index 00000000..a689c31b
--- /dev/null
+++
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/test/java/org/apache/dubbo/common/serialize/fory/ForyObjectInputTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+package org.apache.dubbo.common.serialize.fory;
+
+import org.apache.dubbo.common.serialize.fory.dubbo.ForyObjectInput;
+
+import org.apache.fory.Fory;
+import org.apache.fory.config.Language;
+import org.apache.fory.memory.MemoryBuffer;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class ForyObjectInputTest {
+
+ private Fory fory;
+ private MemoryBuffer buffer;
+ private InputStream inputStream;
+
+ @BeforeEach
+ public void setUp() {
+ fory = Fory.builder().withLanguage(Language.JAVA).build();
+ buffer = MemoryBuffer.newHeapBuffer(1024); // Initialize with an
arbitrary size
+ }
+
+ @Test
+ public void testReadBool() throws Exception {
+ byte[] inputBytes = new byte[]{1};
+ inputStream = new ByteArrayInputStream(inputBytes);
+ ForyObjectInput objectInput = new ForyObjectInput(fory, buffer,
inputStream);
+
+ boolean result = objectInput.readBool();
+ assertTrue(result);
+ }
+
+ @Test
+ public void testReadByte() throws Exception {
+ byte[] inputBytes = new byte[]{0x1F};
+ inputStream = new ByteArrayInputStream(inputBytes);
+ ForyObjectInput objectInput = new ForyObjectInput(fory, buffer,
inputStream);
+
+ byte result = objectInput.readByte();
+ assertEquals(0x1F, result);
+ }
+
+ @Test
+ public void testReadInt() throws Exception {
+ byte[] inputBytes = new byte[]{42, 0, 0, 0};
+ inputStream = new ByteArrayInputStream(inputBytes);
+ ForyObjectInput objectInput = new ForyObjectInput(fory, buffer,
inputStream);
+
+ int result = objectInput.readInt();
+ assertEquals(42, result);
+ }
+
+ @Test
+ public void testReadShort() throws Exception {
+ byte[] inputBytes = new byte[]{42, 0};
+ inputStream = new ByteArrayInputStream(inputBytes);
+ ForyObjectInput objectInput = new ForyObjectInput(fory, buffer,
inputStream);
+
+ short result = objectInput.readShort();
+ assertEquals(42, result);
+ }
+
+
+ @Test
+ public void testReadLong() throws Exception {
+ byte[] inputBytes = new byte[]{42, 0, 0, 0, 0, 0, 0, 0};
+ inputStream = new ByteArrayInputStream(inputBytes);
+ ForyObjectInput objectInput = new ForyObjectInput(fory, buffer,
inputStream);
+
+ long result = objectInput.readLong();
+ assertEquals(42L, result);
+ }
+
+ @Test
+ public void testReadBytes() throws Exception {
+ byte[] inputBytes = new byte[]{4, 0, 0, 0, 10, 20, 30, 40};
+ inputStream = new ByteArrayInputStream(inputBytes);
+ ForyObjectInput objectInput = new ForyObjectInput(fory, buffer,
inputStream);
+
+ byte[] result = objectInput.readBytes();
+ assertArrayEquals(new byte[]{10, 20, 30, 40}, result);
+ }
+}
diff --git
a/dubbo-serialization-extensions/dubbo-serialization-fory/src/test/java/org/apache/dubbo/common/serialize/fory/ForyObjectOutputTest.java
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/test/java/org/apache/dubbo/common/serialize/fory/ForyObjectOutputTest.java
new file mode 100644
index 00000000..5b64a158
--- /dev/null
+++
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/test/java/org/apache/dubbo/common/serialize/fory/ForyObjectOutputTest.java
@@ -0,0 +1,196 @@
+/*
+ * 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.
+ */
+
+package org.apache.dubbo.common.serialize.fory;
+
+import org.apache.dubbo.common.serialize.fory.dubbo.ForyObjectInput;
+import org.apache.dubbo.common.serialize.fory.dubbo.ForyObjectOutput;
+import org.apache.dubbo.common.serialize.model.AnimalEnum;
+import org.apache.dubbo.common.serialize.model.person.FullAddress;
+import org.apache.fory.Fory;
+import org.apache.fory.config.Language;
+import org.apache.fory.memory.MemoryBuffer;
+import org.apache.fory.memory.MemoryUtils;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class ForyObjectOutputTest {
+ private ForyObjectOutput foryObjectOutput;
+ private ForyObjectInput foryObjectInput;
+ private ByteArrayOutputStream byteArrayOutputStream;
+ private ByteArrayInputStream byteArrayInputStream;
+ Fory fory = Fory.builder().withLanguage(Language.JAVA).build();
+ MemoryBuffer buffer = MemoryUtils.buffer(32);
+
+ @BeforeEach
+ public void setUp() {
+ this.byteArrayOutputStream = new ByteArrayOutputStream();
+ this.foryObjectOutput = new ForyObjectOutput(fory,
buffer,byteArrayOutputStream);
+ }
+
+ @AfterEach
+ public void tearDown() {
+ new ForyObjectInput(fory,buffer,new ByteArrayInputStream(new
byte[]{0}));
+ }
+
+ @Test
+ public void testWriteBool() throws IOException {
+ this.foryObjectOutput.writeBool(false);
+ this.flushToInput();
+
+ boolean result = this.foryObjectInput.readBool();
+ assertThat(result, is(false));
+ }
+
+
+ @Test
+ public void testWriteUTF() throws IOException {
+ this.foryObjectOutput.writeUTF("I don’t know 知りません Не знаю");
+ this.flushToInput();
+
+ String result = this.foryObjectInput.readUTF();
+ assertThat(result, is("I don’t know 知りません Не знаю"));
+ }
+
+ @Test
+ public void testWriteShort() throws IOException {
+ this.foryObjectOutput.writeShort((short) 1);
+ this.flushToInput();
+
+ Short result = this.foryObjectInput.readShort();
+ assertThat(result, is((short) 1));
+ }
+
+ @Test
+ public void testWriteLong() throws IOException {
+ this.foryObjectOutput.writeLong(12345678L);
+ this.flushToInput();
+
+ Long result = this.foryObjectInput.readLong();
+ assertThat(result, is(12345678L));
+ }
+
+ @Test
+ public void testWriteDouble() throws IOException {
+ this.foryObjectOutput.writeDouble(-1.66d);
+ this.flushToInput();
+
+ Double result = this.foryObjectInput.readDouble();
+ assertThat(result, is(-1.66d));
+ }
+
+
+ @Test
+ public void testWriteInt() throws IOException {
+ this.foryObjectOutput.writeInt(1);
+ this.flushToInput();
+
+ Integer result = this.foryObjectInput.readInt();
+ assertThat(result, is(1));
+ }
+
+ @Test
+ public void testWriteByte() throws IOException {
+ this.foryObjectOutput.writeByte((byte) 222);
+ this.flushToInput();
+
+ Byte result = this.foryObjectInput.readByte();
+ assertThat(result, is(((byte) 222)));
+ }
+
+ @Test
+ public void testWriteBytesWithSubLength() throws IOException {
+ this.foryObjectOutput.writeBytes("who are you".getBytes(), 4, 3);
+ this.flushToInput();
+
+ byte[] result = this.foryObjectInput.readBytes();
+ assertThat(result, is("are".getBytes()));
+ }
+
+ @Test
+ public void testWriteBytes() throws IOException {
+ this.foryObjectOutput.writeBytes("who are you".getBytes());
+ this.flushToInput();
+
+ byte[] result = this.foryObjectInput.readBytes();
+ assertThat(result, is("who are you".getBytes()));
+ }
+
+ @Test
+ public void testWriteFloat() throws IOException {
+ this.foryObjectOutput.writeFloat(-666.66f);
+ this.flushToInput();
+
+ Float result = this.foryObjectInput.readFloat();
+ assertThat(result, is(-666.66f));
+ }
+
+ @Test
+ public void testWriteNullBytesWithSubLength() throws IOException {
+ Assertions.assertThrows(NullPointerException.class, () -> {
+ this.foryObjectOutput.writeBytes(null, 4, 3);
+ this.flushToInput();
+ this.foryObjectInput.readBytes();
+ });
+
+ }
+
+ @Test
+ public void testWriteNullBytes() throws IOException {
+ Assertions.assertThrows(NullPointerException.class, () -> {
+ this.foryObjectOutput.writeBytes(null);
+ this.flushToInput();
+ this.foryObjectInput.readBytes();
+ });
+ }
+
+ @Test
+ public void testWriteObject() throws IOException, ClassNotFoundException {
+ fory.register(FullAddress.class);
+ FullAddress fullAddress = new FullAddress("cId", "pN", "cityId", "Nan
Long Street", "51000");
+ this.foryObjectOutput.writeObject(fullAddress);
+ this.flushToInput();
+
+ FullAddress result =
this.foryObjectInput.readObject(FullAddress.class);
+ assertThat(result, is(fullAddress));
+ }
+
+ @Test
+ public void testWriteEnum() throws IOException, ClassNotFoundException {
+ fory.register(AnimalEnum.class);
+ this.foryObjectOutput.writeObject(AnimalEnum.cat);
+ this.flushToInput();
+
+ AnimalEnum animalEnum = (AnimalEnum) this.foryObjectInput.readObject();
+ assertThat(animalEnum, is(AnimalEnum.cat));
+ }
+
+ private void flushToInput() throws IOException {
+ this.foryObjectOutput.flushBuffer();
+ this.byteArrayInputStream = new
ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+ this.foryObjectInput = new
ForyObjectInput(fory,buffer,byteArrayInputStream);
+ }
+}
diff --git
a/dubbo-serialization-extensions/dubbo-serialization-fory/src/test/java/org/apache/dubbo/common/serialize/fory/ForySerializationTest.java
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/test/java/org/apache/dubbo/common/serialize/fory/ForySerializationTest.java
new file mode 100644
index 00000000..5854f9c0
--- /dev/null
+++
b/dubbo-serialization-extensions/dubbo-serialization-fory/src/test/java/org/apache/dubbo/common/serialize/fory/ForySerializationTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+package org.apache.dubbo.common.serialize.fory;
+
+import org.apache.dubbo.common.serialize.ObjectInput;
+import org.apache.dubbo.common.serialize.ObjectOutput;
+import org.apache.dubbo.common.serialize.fory.dubbo.ForyObjectInput;
+import org.apache.dubbo.common.serialize.fory.dubbo.ForyObjectOutput;
+import org.apache.dubbo.common.serialize.fory.dubbo.ForySerialization;
+
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+
+public class ForySerializationTest {
+ private ForySerialization fstSerialization;
+
+ @BeforeEach
+ public void setUp() {
+ this.fstSerialization = new ForySerialization();
+ }
+
+ @Test
+ public void testContentTypeId() {
+ assertThat(fstSerialization.getContentTypeId(), is((byte) 28));
+ }
+
+ @Test
+ public void testContentType() {
+ assertThat(fstSerialization.getContentType(), is("fory/consistent"));
+ }
+
+ @Test
+ public void testSerialize() throws IOException {
+ ObjectOutput objectOutput = fstSerialization.serialize(null,
mock(OutputStream.class));
+ assertThat(objectOutput, Matchers.instanceOf(ForyObjectOutput.class));
+ }
+
+ @Test
+ public void testDeserialize() throws IOException {
+ ObjectInput objectInput = fstSerialization.deserialize(null,
mock(InputStream.class));
+ assertThat(objectInput, Matchers.instanceOf(ForyObjectInput.class));
+ }
+}
diff --git a/dubbo-serialization-extensions/pom.xml
b/dubbo-serialization-extensions/pom.xml
index cec14402..5addd5e2 100644
--- a/dubbo-serialization-extensions/pom.xml
+++ b/dubbo-serialization-extensions/pom.xml
@@ -40,6 +40,7 @@
<module>dubbo-serialization-fst</module>
<module>dubbo-serialization-fastjson</module>
<module>dubbo-serialization-fury</module>
+ <module>dubbo-serialization-fory</module>
<module>dubbo-serialization-avro</module>
<module>dubbo-serialization-msgpack</module>
<module>dubbo-serialization-native-hessian</module>