Skip to content

Commit 1f1528f

Browse files
authored
feat(java): support graalvm 17/21/22 (#1845)
## What does this PR do? - Support graalvm 17/21/22 - Add ci for Fury graalvm 17/22 support ## Related issues #1813 ## Does this PR introduce any user-facing change? <!-- If any user-facing interface changes, please [open an issue](https://github.com/apache/fury/issues/new/choose) describing the need to do so and update the document if necessary. --> - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark <!-- When the PR has an impact on performance (if you don't know whether the PR will have an impact on performance, you can submit the PR first, and if it will have impact on performance, the code reviewer will explain it), be sure to attach a benchmark data here. -->
1 parent d15c709 commit 1f1528f

File tree

20 files changed

+939
-186
lines changed

20 files changed

+939
-186
lines changed

.github/workflows/ci.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,14 @@ jobs:
8989
graalvm:
9090
name: GraalVM CI
9191
runs-on: ubuntu-latest
92+
strategy:
93+
matrix:
94+
java-version: ["17", "21", "22"]
9295
steps:
9396
- uses: actions/checkout@v4
9497
- uses: graalvm/setup-graalvm@v1
9598
with:
96-
java-version: "21"
99+
java-version: ${{ matrix.java-version }}
97100
distribution: "graalvm"
98101
github-token: ${{ secrets.GITHUB_TOKEN }}
99102
native-image-job-reports: "true"

integration_tests/graalvm_tests/src/main/java/org/apache/fury/graalvm/CollectionExample.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ public class CollectionExample {
3232
static Fury fury;
3333

3434
static {
35-
fury = Fury.builder().requireClassRegistration(true).build();
35+
fury =
36+
Fury.builder()
37+
.withName(CollectionExample.class.getName())
38+
.requireClassRegistration(true)
39+
.build();
3640
}
3741

3842
static void test(Fury fury) {

integration_tests/graalvm_tests/src/main/java/org/apache/fury/graalvm/CompatibleExample.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,27 @@ public class CompatibleExample {
2626
static Fury fury;
2727

2828
static {
29-
fury =
29+
fury = createFury();
30+
}
31+
32+
private static Fury createFury() {
33+
Fury fury =
3034
Fury.builder()
3135
.requireClassRegistration(true)
3236
.withCompatibleMode(CompatibleMode.COMPATIBLE)
3337
.withScopedMetaShare(false)
3438
.build();
3539
// register and generate serializer code.
3640
fury.register(Foo.class, true);
41+
return fury;
3742
}
3843

3944
public static void main(String[] args) {
45+
System.out.println("CompatibleExample started");
46+
Example.test(fury);
47+
System.out.println("CompatibleExample succeed 1/2");
48+
// Test new created Fury at runtime
49+
fury = createFury();
4050
Example.test(fury);
4151
System.out.println("CompatibleExample succeed");
4252
}

integration_tests/graalvm_tests/src/main/java/org/apache/fury/graalvm/CompatibleThreadSafeExample.java

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public class CompatibleThreadSafeExample {
3333
classLoader -> {
3434
Fury f =
3535
Fury.builder()
36+
.withName(CompatibleThreadSafeExample.class.getName())
3637
.requireClassRegistration(true)
3738
.withCompatibleMode(CompatibleMode.COMPATIBLE)
3839
.build();

integration_tests/graalvm_tests/src/main/java/org/apache/fury/graalvm/Example.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public class Example {
2828
static Fury fury;
2929

3030
static {
31-
fury = Fury.builder().requireClassRegistration(true).build();
31+
fury = Fury.builder().withName(Example.class.getName()).requireClassRegistration(true).build();
3232
// register and generate serializer code.
3333
fury.register(Foo.class, true);
3434
}

integration_tests/graalvm_tests/src/main/java/org/apache/fury/graalvm/Main.java

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public static void main(String[] args) throws Throwable {
3131
RecordExample.main(args);
3232
CompatibleRecordExample.main(args);
3333
RecordExample2.main(args);
34+
3435
ThreadSafeExample.main(args);
3536
CompatibleThreadSafeExample.main(args);
3637
ProxyExample.main(args);

integration_tests/graalvm_tests/src/main/java/org/apache/fury/graalvm/ProxyExample.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,18 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
3939
static Fury fury;
4040

4141
static {
42-
fury = Fury.builder().requireClassRegistration(true).build();
42+
fury = createFury();
43+
}
44+
45+
private static Fury createFury() {
46+
Fury fury =
47+
Fury.builder()
48+
.withName(ProxyExample.class.getName())
49+
.requireClassRegistration(true)
50+
.build();
4351
// register and generate serializer code.
4452
fury.register(TestInvocationHandler.class, true);
53+
return fury;
4554
}
4655

4756
public static void main(String[] args) {
@@ -51,6 +60,9 @@ public static void main(String[] args) {
5160
fury.getClassLoader(), new Class[] {Function.class}, new TestInvocationHandler());
5261
Function deserializedFunction = (Function) fury.deserialize(fury.serialize(function));
5362
Preconditions.checkArgument(deserializedFunction.apply(null).equals(1));
63+
fury = createFury();
64+
deserializedFunction = (Function) fury.deserialize(fury.serialize(function));
65+
Preconditions.checkArgument(deserializedFunction.apply(null).equals(1));
5466
System.out.println("Proxy tests pass");
5567
}
5668
}

integration_tests/graalvm_tests/src/main/java/org/apache/fury/graalvm/ScopedCompatibleExample.java

+13-3
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,31 @@
2323
import org.apache.fury.config.CompatibleMode;
2424

2525
public class ScopedCompatibleExample {
26-
static Fury fury;
26+
private static Fury fury;
2727

2828
static {
29-
fury =
29+
fury = createFury();
30+
}
31+
32+
private static Fury createFury() {
33+
Fury fury =
3034
Fury.builder()
35+
.withName(ScopedCompatibleExample.class.getName())
3136
.requireClassRegistration(true)
3237
.withCompatibleMode(CompatibleMode.COMPATIBLE)
3338
.withScopedMetaShare(true)
3439
.build();
3540
// register and generate serializer code.
3641
fury.register(Foo.class, true);
42+
return fury;
3743
}
3844

3945
public static void main(String[] args) {
46+
System.out.println("ScopedCompatibleExample started");
47+
Example.test(fury);
48+
System.out.println("ScopedCompatibleExample succeed 1/2");
49+
fury = createFury();
4050
Example.test(fury);
41-
System.out.println("CompatibleExample succeed");
51+
System.out.println("ScopedCompatibleExample succeed");
4252
}
4353
}

integration_tests/graalvm_tests/src/main/java/org/apache/fury/graalvm/ThreadSafeExample.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ public class ThreadSafeExample {
3737
fury =
3838
new ThreadLocalFury(
3939
classLoader -> {
40-
Fury f = Fury.builder().requireClassRegistration(true).build();
40+
Fury f =
41+
Fury.builder()
42+
.withName(ThreadSafeExample.class.getName())
43+
.requireClassRegistration(true)
44+
.build();
4145
// register and generate serializer code.
4246
f.register(Foo.class, true);
4347
return f;

integration_tests/graalvm_tests/src/main/java/org/apache/fury/graalvm/record/CompatibleRecordExample.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,24 @@ public class CompatibleRecordExample {
2626
static Fury fury;
2727

2828
static {
29-
fury =
29+
fury = createFury();
30+
}
31+
32+
private static Fury createFury() {
33+
Fury fury =
3034
Fury.builder()
35+
.withName(CompatibleRecordExample.class.getName())
3136
.requireClassRegistration(true)
3237
.withCompatibleMode(CompatibleMode.COMPATIBLE)
3338
.build();
3439
// register and generate serializer code.
3540
fury.register(RecordExample.Record.class, true);
41+
return fury;
3642
}
3743

3844
public static void main(String[] args) {
45+
RecordExample.test(fury);
46+
fury = createFury();
3947
RecordExample.test(fury);
4048
System.out.println("CompatibleRecordExample succeed");
4149
}

integration_tests/graalvm_tests/src/main/java/org/apache/fury/graalvm/record/RecordExample.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,18 @@ public record Record(int f1, String f2, List<String> f3, Map<String, Long> f4) {
3030
static Fury fury;
3131

3232
static {
33-
fury = Fury.builder().requireClassRegistration(true).build();
33+
fury = createFury();
34+
}
35+
36+
private static Fury createFury() {
37+
Fury fury =
38+
Fury.builder()
39+
.withName(RecordExample.class.getName())
40+
.requireClassRegistration(true)
41+
.build();
3442
// register and generate serializer code.
3543
fury.register(Record.class, true);
44+
return fury;
3645
}
3746

3847
static void test(Fury fury) {
@@ -45,6 +54,10 @@ static void test(Fury fury) {
4554
}
4655

4756
public static void main(String[] args) {
57+
System.out.println("RecordExample started");
58+
test(fury);
59+
System.out.println("RecordExample succeed 1/2");
60+
fury = createFury();
4861
test(fury);
4962
System.out.println("RecordExample succeed");
5063
}

integration_tests/graalvm_tests/src/main/java/org/apache/fury/graalvm/record/RecordExample2.java

+19-2
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,37 @@ private record Record(int f1, String f2, List<String> f3, Map<String, Long> f4)
3030
static Fury fury;
3131

3232
static {
33-
fury = Fury.builder().requireClassRegistration(true).build();
33+
fury = createFury();
34+
}
35+
36+
private static Fury createFury() {
37+
Fury fury =
38+
Fury.builder()
39+
.withName(RecordExample2.class.getName())
40+
.requireClassRegistration(true)
41+
.build();
3442
// register and generate serializer code.
3543
fury.register(Record.class, true);
3644
fury.register(Foo.class, true);
45+
return fury;
3746
}
3847

39-
public static void main(String[] args) {
48+
public static void test(Fury fury) {
4049
Record record = new Record(10, "abc", List.of("str1", "str2"), Map.of("k1", 10L, "k2", 20L));
4150
byte[] bytes = fury.serialize(record);
4251
Object o = fury.deserialize(bytes);
4352
Preconditions.checkArgument(record.equals(o));
4453
Foo foo = new Foo(10, "abc", List.of("str1", "str2"), Map.of("k1", 10L, "k2", 20L));
4554
Object o2 = fury.deserialize(fury.serialize(foo));
4655
Preconditions.checkArgument(foo.equals(o2));
56+
}
57+
58+
public static void main(String[] args) {
59+
System.out.println("RecordExample started");
60+
test(fury);
61+
System.out.println("RecordExample succeed 1/2");
62+
fury = createFury();
63+
test(fury);
4764
System.out.println("RecordExample2 succeed");
4865
}
4966
}

integration_tests/graalvm_tests/src/main/resources/META-INF/native-image/org.apache.fury/graalvm_tests/native-image.properties

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717

1818
# https://www.graalvm.org/latest/reference-manual/native-image/dynamic-features/Reflection/#unsafe-accesses :
1919
# The unsafe offset get on build time may be different from runtime
20-
Args = -H:+ReportExceptionStackTraces \
20+
Args=-H:+ReportExceptionStackTraces \
2121
--initialize-at-build-time=org.apache.fury.graalvm.Example,\
2222
org.apache.fury.graalvm.CompatibleExample,\
23+
org.apache.fury.graalvm.ScopedCompatibleExample,\
2324
org.apache.fury.graalvm.record.RecordExample,\
2425
org.apache.fury.graalvm.record.CompatibleRecordExample,\
2526
org.apache.fury.graalvm.record.RecordExample2,\
2627
org.apache.fury.graalvm.ThreadSafeExample,\
2728
org.apache.fury.graalvm.CompatibleThreadSafeExample,\
2829
org.apache.fury.graalvm.ProxyExample,\
30+
org.apache.fury.graalvm.CollectionExample,\
2931
org.apache.fury.graalvm.Benchmark

java/fury-core/src/main/java/org/apache/fury/ThreadLocalFury.java

-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import org.apache.fury.io.FuryReadableChannel;
3030
import org.apache.fury.memory.MemoryBuffer;
3131
import org.apache.fury.memory.MemoryUtils;
32-
import org.apache.fury.resolver.ClassResolver;
3332
import org.apache.fury.serializer.BufferCallback;
3433
import org.apache.fury.util.LoaderBinding;
3534
import org.apache.fury.util.LoaderBinding.StagingType;
@@ -65,8 +64,6 @@ public ThreadLocalFury(Function<ClassLoader, Fury> furyFactory) {
6564
// in a process load some classes which is not cheap.
6665
// 2. Make fury generate code at graalvm build time.
6766
Fury fury = bindingThreadLocal.get().get();
68-
ClassResolver._addGraalvmClassRegistry(
69-
fury.getConfig().getConfigHash(), fury.getClassResolver());
7067
}
7168

7269
@Override

java/fury-core/src/main/java/org/apache/fury/config/Config.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
/** Config for fury, all {@link Fury} related config can be found here. */
3434
@SuppressWarnings({"rawtypes"})
3535
public class Config implements Serializable {
36+
private final String name;
3637
private final Language language;
3738
private final boolean trackingRef;
3839
private final boolean basicTypesRefIgnored;
@@ -61,6 +62,7 @@ public class Config implements Serializable {
6162
private final boolean deserializeNonexistentEnumValueAsNull;
6263

6364
public Config(FuryBuilder builder) {
65+
name = builder.name;
6466
language = builder.language;
6567
trackingRef = builder.trackingRef;
6668
basicTypesRefIgnored = !trackingRef || builder.basicTypesRefIgnored;
@@ -93,6 +95,11 @@ public Config(FuryBuilder builder) {
9395
deserializeNonexistentEnumValueAsNull = builder.deserializeNonexistentEnumValueAsNull;
9496
}
9597

98+
/** Returns the name for Fury serialization. */
99+
public String getName() {
100+
return name;
101+
}
102+
96103
public Language getLanguage() {
97104
return language;
98105
}
@@ -257,7 +264,8 @@ public boolean equals(Object o) {
257264
return false;
258265
}
259266
Config config = (Config) o;
260-
return trackingRef == config.trackingRef
267+
return name == config.name
268+
&& trackingRef == config.trackingRef
261269
&& basicTypesRefIgnored == config.basicTypesRefIgnored
262270
&& stringRefIgnored == config.stringRefIgnored
263271
&& timeRefIgnored == config.timeRefIgnored
@@ -286,6 +294,7 @@ public boolean equals(Object o) {
286294
@Override
287295
public int hashCode() {
288296
return Objects.hash(
297+
name,
289298
language,
290299
trackingRef,
291300
basicTypesRefIgnored,

java/fury-core/src/main/java/org/apache/fury/config/FuryBuilder.java

+7
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public final class FuryBuilder {
5656
ENABLE_CLASS_REGISTRATION_FORCIBLY = "true".equals(flagValue) || "1".equals(flagValue);
5757
}
5858

59+
String name;
5960
boolean checkClassVersion = false;
6061
Language language = Language.JAVA;
6162
boolean trackingRef = false;
@@ -318,6 +319,12 @@ public FuryBuilder withScalaOptimizationEnabled(boolean enableScalaOptimization)
318319
return this;
319320
}
320321

322+
/** Set name for Fury serialization. */
323+
public FuryBuilder withName(String name) {
324+
this.name = name;
325+
return this;
326+
}
327+
321328
private void finish() {
322329
if (classLoader == null) {
323330
classLoader = Thread.currentThread().getContextClassLoader();

0 commit comments

Comments
 (0)