Skip to content

Commit 8cc7a69

Browse files
committed
Compatible with Fory
1 parent 373b5b9 commit 8cc7a69

File tree

5 files changed

+166
-36
lines changed

5 files changed

+166
-36
lines changed

serializer/seata-serializer-fury/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@
4141
<dependency>
4242
<groupId>org.apache.fury</groupId>
4343
<artifactId>fury-core</artifactId>
44+
<scope>provided</scope>
45+
</dependency>
46+
<dependency>
47+
<groupId>org.apache.fory</groupId>
48+
<artifactId>fory-core</artifactId>
4449
</dependency>
4550
</dependencies>
4651
</project>

serializer/seata-serializer-fury/src/main/java/org/apache/seata/serializer/fury/FurySerializer.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
*/
1717
package org.apache.seata.serializer.fury;
1818

19-
import org.apache.fury.ThreadSafeFury;
2019
import org.apache.seata.common.loader.LoadLevel;
2120
import org.apache.seata.core.protocol.AbstractMessage;
2221
import org.apache.seata.core.serializer.Serializer;
@@ -28,16 +27,14 @@ public <T> byte[] serialize(T t) {
2827
if (!(t instanceof AbstractMessage)) {
2928
throw new IllegalArgumentException("AbstractMessage isn't available.");
3029
}
31-
ThreadSafeFury threadSafeFury = FurySerializerFactory.getInstance().get();
32-
return threadSafeFury.serialize(t);
30+
return FurySerializerFactory.getInstance().serialize(t);
3331
}
3432

3533
@Override
3634
public <T> T deserialize(byte[] bytes) {
3735
if (bytes == null || bytes.length == 0) {
3836
throw new IllegalArgumentException("bytes is null");
3937
}
40-
ThreadSafeFury threadSafeFury = FurySerializerFactory.getInstance().get();
41-
return (T) threadSafeFury.deserialize(bytes);
38+
return (T) FurySerializerFactory.getInstance().deserialize(bytes);
4239
}
4340
}

serializer/seata-serializer-fury/src/main/java/org/apache/seata/serializer/fury/FurySerializerFactory.java

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,49 @@
1616
*/
1717
package org.apache.seata.serializer.fury;
1818

19-
import org.apache.fury.Fury;
20-
import org.apache.fury.ThreadLocalFury;
21-
import org.apache.fury.ThreadSafeFury;
22-
import org.apache.fury.config.CompatibleMode;
23-
import org.apache.fury.config.Language;
24-
import org.apache.seata.core.serializer.SerializerSecurityRegistry;
19+
import org.apache.seata.core.serializer.Serializer;
20+
21+
import java.util.function.Function;
2522

2623
public class FurySerializerFactory {
2724
private static final FurySerializerFactory FACTORY = new FurySerializerFactory();
2825

29-
private static final ThreadSafeFury FURY = new ThreadLocalFury(classLoader -> {
30-
Fury f = Fury.builder()
31-
.withLanguage(Language.JAVA)
32-
// In JAVA mode, classes cannot be registered by tag, and the different registration order between the
33-
// server and the client will cause deserialization failure
34-
// In XLANG cross-language mode has problems with Java class serialization, such as enum classes
35-
// [https://github.com/apache/fury/issues/1644].
36-
.requireClassRegistration(false)
37-
// enable reference tracking for shared/circular reference.
38-
.withRefTracking(true)
39-
.withClassLoader(classLoader)
40-
.withCompatibleMode(CompatibleMode.COMPATIBLE)
41-
.build();
42-
43-
// register allow class
44-
f.getClassResolver()
45-
.setClassChecker((classResolver, className) ->
46-
SerializerSecurityRegistry.getAllowClassPattern().contains(className));
47-
return f;
48-
});
49-
50-
public static FurySerializerFactory getInstance() {
51-
return FACTORY;
26+
private static final SerializerDelegate INSTANCE = new SerializerDelegate();
27+
28+
public static Serializer getInstance() {
29+
return INSTANCE;
30+
}
31+
32+
public Serializer get() {
33+
return INSTANCE;
5234
}
5335

54-
public ThreadSafeFury get() {
55-
return FURY;
36+
private static class SerializerDelegate implements Serializer {
37+
private static Function<Object, byte[]> serializer;
38+
private static Function<byte[], Object> deserializer;
39+
40+
static {
41+
try {
42+
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
43+
classLoader.loadClass("org.apache.fory.ThreadSafeFory");
44+
InnerFory innerFory = new InnerFory();
45+
serializer = innerFory.new SerializerFunction();
46+
deserializer = innerFory.new DeserializerFunction();
47+
} catch (ClassNotFoundException e) {
48+
InnerFury innerFury = new InnerFury();
49+
serializer = innerFury.new SerializerFunction();
50+
deserializer = innerFury.new DeserializerFunction();
51+
}
52+
}
53+
54+
@Override
55+
public <T> byte[] serialize(T t) {
56+
return serializer.apply(t);
57+
}
58+
59+
@Override
60+
public <T> T deserialize(byte[] bytes) {
61+
return (T) deserializer.apply(bytes);
62+
}
5663
}
5764
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package org.apache.seata.serializer.fury;
2+
3+
import org.apache.fory.Fory;
4+
import org.apache.fory.ThreadLocalFory;
5+
import org.apache.fory.ThreadSafeFory;
6+
import org.apache.fory.config.CompatibleMode;
7+
import org.apache.fory.config.Language;
8+
import org.apache.seata.core.serializer.SerializerSecurityRegistry;
9+
10+
import java.util.function.Function;
11+
12+
class InnerFory {
13+
14+
ThreadSafeFory instance;
15+
16+
ThreadSafeFory get() {
17+
if (instance == null) {
18+
synchronized (InnerFory.class) {
19+
if (instance == null) {
20+
instance = new ThreadLocalFory(classLoader -> {
21+
Fory f = Fory.builder()
22+
.withLanguage(Language.JAVA)
23+
// In JAVA mode, classes cannot be registered by tag, and the different registration order between the
24+
// server and the client will cause deserialization failure
25+
// In XLANG cross-language mode has problems with Java class serialization, such as enum classes
26+
// [https://github.com/apache/fory/issues/1644].
27+
.requireClassRegistration(false)
28+
// enable reference tracking for shared/circular reference.
29+
.withRefTracking(true)
30+
.withClassLoader(classLoader)
31+
.withCompatibleMode(CompatibleMode.COMPATIBLE)
32+
.build();
33+
34+
// register allow class
35+
f.getClassResolver()
36+
.setClassChecker((classResolver, className) ->
37+
SerializerSecurityRegistry.getAllowClassPattern().contains(className));
38+
return f;
39+
});
40+
}
41+
}
42+
}
43+
return instance;
44+
}
45+
46+
class SerializerFunction implements Function<Object, byte[]> {
47+
@Override
48+
public byte[] apply(Object o) {
49+
return get().serialize(o);
50+
}
51+
}
52+
53+
class DeserializerFunction implements Function<byte[], Object> {
54+
@Override
55+
public Object apply(byte[] bytes) {
56+
return get().deserialize(bytes);
57+
}
58+
}
59+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package org.apache.seata.serializer.fury;
2+
3+
import org.apache.fury.Fury;
4+
import org.apache.fury.ThreadLocalFury;
5+
import org.apache.fury.ThreadSafeFury;
6+
import org.apache.fury.config.CompatibleMode;
7+
import org.apache.fury.config.Language;
8+
import org.apache.seata.core.serializer.SerializerSecurityRegistry;
9+
10+
import java.util.function.Function;
11+
12+
class InnerFury {
13+
14+
ThreadSafeFury instance;
15+
16+
ThreadSafeFury get() {
17+
if (instance == null) {
18+
synchronized (InnerFury.class) {
19+
if (instance == null) {
20+
instance = new ThreadLocalFury(classLoader -> {
21+
Fury f = Fury.builder()
22+
.withLanguage(Language.JAVA)
23+
// In JAVA mode, classes cannot be registered by tag, and the different registration order between the
24+
// server and the client will cause deserialization failure
25+
// In XLANG cross-language mode has problems with Java class serialization, such as enum classes
26+
// [https://github.com/apache/fury/issues/1644].
27+
.requireClassRegistration(false)
28+
// enable reference tracking for shared/circular reference.
29+
.withRefTracking(true)
30+
.withClassLoader(classLoader)
31+
.withCompatibleMode(CompatibleMode.COMPATIBLE)
32+
.build();
33+
34+
// register allow class
35+
f.getClassResolver()
36+
.setClassChecker((classResolver, className) ->
37+
SerializerSecurityRegistry.getAllowClassPattern().contains(className));
38+
return f;
39+
});
40+
}
41+
}
42+
}
43+
return instance;
44+
}
45+
46+
class SerializerFunction implements Function<Object, byte[]> {
47+
@Override
48+
public byte[] apply(Object o) {
49+
return get().serialize(o);
50+
}
51+
}
52+
53+
class DeserializerFunction implements Function<byte[], Object> {
54+
@Override
55+
public Object apply(byte[] bytes) {
56+
return get().deserialize(bytes);
57+
}
58+
}
59+
}
60+
61+
62+

0 commit comments

Comments
 (0)