Skip to content

Commit

Permalink
feat(java): support graalvm 17/21/22 (#1845)
Browse files Browse the repository at this point in the history
## 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.
-->
  • Loading branch information
chaokunyang authored Sep 23, 2024
1 parent d15c709 commit 1f1528f
Show file tree
Hide file tree
Showing 20 changed files with 939 additions and 186 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,14 @@ jobs:
graalvm:
name: GraalVM CI
runs-on: ubuntu-latest
strategy:
matrix:
java-version: ["17", "21", "22"]
steps:
- uses: actions/checkout@v4
- uses: graalvm/setup-graalvm@v1
with:
java-version: "21"
java-version: ${{ matrix.java-version }}
distribution: "graalvm"
github-token: ${{ secrets.GITHUB_TOKEN }}
native-image-job-reports: "true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ public class CollectionExample {
static Fury fury;

static {
fury = Fury.builder().requireClassRegistration(true).build();
fury =
Fury.builder()
.withName(CollectionExample.class.getName())
.requireClassRegistration(true)
.build();
}

static void test(Fury fury) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,27 @@ public class CompatibleExample {
static Fury fury;

static {
fury =
fury = createFury();
}

private static Fury createFury() {
Fury fury =
Fury.builder()
.requireClassRegistration(true)
.withCompatibleMode(CompatibleMode.COMPATIBLE)
.withScopedMetaShare(false)
.build();
// register and generate serializer code.
fury.register(Foo.class, true);
return fury;
}

public static void main(String[] args) {
System.out.println("CompatibleExample started");
Example.test(fury);
System.out.println("CompatibleExample succeed 1/2");
// Test new created Fury at runtime
fury = createFury();
Example.test(fury);
System.out.println("CompatibleExample succeed");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class CompatibleThreadSafeExample {
classLoader -> {
Fury f =
Fury.builder()
.withName(CompatibleThreadSafeExample.class.getName())
.requireClassRegistration(true)
.withCompatibleMode(CompatibleMode.COMPATIBLE)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class Example {
static Fury fury;

static {
fury = Fury.builder().requireClassRegistration(true).build();
fury = Fury.builder().withName(Example.class.getName()).requireClassRegistration(true).build();
// register and generate serializer code.
fury.register(Foo.class, true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public static void main(String[] args) throws Throwable {
RecordExample.main(args);
CompatibleRecordExample.main(args);
RecordExample2.main(args);

ThreadSafeExample.main(args);
CompatibleThreadSafeExample.main(args);
ProxyExample.main(args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,18 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
static Fury fury;

static {
fury = Fury.builder().requireClassRegistration(true).build();
fury = createFury();
}

private static Fury createFury() {
Fury fury =
Fury.builder()
.withName(ProxyExample.class.getName())
.requireClassRegistration(true)
.build();
// register and generate serializer code.
fury.register(TestInvocationHandler.class, true);
return fury;
}

public static void main(String[] args) {
Expand All @@ -51,6 +60,9 @@ public static void main(String[] args) {
fury.getClassLoader(), new Class[] {Function.class}, new TestInvocationHandler());
Function deserializedFunction = (Function) fury.deserialize(fury.serialize(function));
Preconditions.checkArgument(deserializedFunction.apply(null).equals(1));
fury = createFury();
deserializedFunction = (Function) fury.deserialize(fury.serialize(function));
Preconditions.checkArgument(deserializedFunction.apply(null).equals(1));
System.out.println("Proxy tests pass");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,31 @@
import org.apache.fury.config.CompatibleMode;

public class ScopedCompatibleExample {
static Fury fury;
private static Fury fury;

static {
fury =
fury = createFury();
}

private static Fury createFury() {
Fury fury =
Fury.builder()
.withName(ScopedCompatibleExample.class.getName())
.requireClassRegistration(true)
.withCompatibleMode(CompatibleMode.COMPATIBLE)
.withScopedMetaShare(true)
.build();
// register and generate serializer code.
fury.register(Foo.class, true);
return fury;
}

public static void main(String[] args) {
System.out.println("ScopedCompatibleExample started");
Example.test(fury);
System.out.println("ScopedCompatibleExample succeed 1/2");
fury = createFury();
Example.test(fury);
System.out.println("CompatibleExample succeed");
System.out.println("ScopedCompatibleExample succeed");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ public class ThreadSafeExample {
fury =
new ThreadLocalFury(
classLoader -> {
Fury f = Fury.builder().requireClassRegistration(true).build();
Fury f =
Fury.builder()
.withName(ThreadSafeExample.class.getName())
.requireClassRegistration(true)
.build();
// register and generate serializer code.
f.register(Foo.class, true);
return f;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,24 @@ public class CompatibleRecordExample {
static Fury fury;

static {
fury =
fury = createFury();
}

private static Fury createFury() {
Fury fury =
Fury.builder()
.withName(CompatibleRecordExample.class.getName())
.requireClassRegistration(true)
.withCompatibleMode(CompatibleMode.COMPATIBLE)
.build();
// register and generate serializer code.
fury.register(RecordExample.Record.class, true);
return fury;
}

public static void main(String[] args) {
RecordExample.test(fury);
fury = createFury();
RecordExample.test(fury);
System.out.println("CompatibleRecordExample succeed");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,18 @@ public record Record(int f1, String f2, List<String> f3, Map<String, Long> f4) {
static Fury fury;

static {
fury = Fury.builder().requireClassRegistration(true).build();
fury = createFury();
}

private static Fury createFury() {
Fury fury =
Fury.builder()
.withName(RecordExample.class.getName())
.requireClassRegistration(true)
.build();
// register and generate serializer code.
fury.register(Record.class, true);
return fury;
}

static void test(Fury fury) {
Expand All @@ -45,6 +54,10 @@ static void test(Fury fury) {
}

public static void main(String[] args) {
System.out.println("RecordExample started");
test(fury);
System.out.println("RecordExample succeed 1/2");
fury = createFury();
test(fury);
System.out.println("RecordExample succeed");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,37 @@ private record Record(int f1, String f2, List<String> f3, Map<String, Long> f4)
static Fury fury;

static {
fury = Fury.builder().requireClassRegistration(true).build();
fury = createFury();
}

private static Fury createFury() {
Fury fury =
Fury.builder()
.withName(RecordExample2.class.getName())
.requireClassRegistration(true)
.build();
// register and generate serializer code.
fury.register(Record.class, true);
fury.register(Foo.class, true);
return fury;
}

public static void main(String[] args) {
public static void test(Fury fury) {
Record record = new Record(10, "abc", List.of("str1", "str2"), Map.of("k1", 10L, "k2", 20L));
byte[] bytes = fury.serialize(record);
Object o = fury.deserialize(bytes);
Preconditions.checkArgument(record.equals(o));
Foo foo = new Foo(10, "abc", List.of("str1", "str2"), Map.of("k1", 10L, "k2", 20L));
Object o2 = fury.deserialize(fury.serialize(foo));
Preconditions.checkArgument(foo.equals(o2));
}

public static void main(String[] args) {
System.out.println("RecordExample started");
test(fury);
System.out.println("RecordExample succeed 1/2");
fury = createFury();
test(fury);
System.out.println("RecordExample2 succeed");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@

# https://www.graalvm.org/latest/reference-manual/native-image/dynamic-features/Reflection/#unsafe-accesses :
# The unsafe offset get on build time may be different from runtime
Args = -H:+ReportExceptionStackTraces \
Args=-H:+ReportExceptionStackTraces \
--initialize-at-build-time=org.apache.fury.graalvm.Example,\
org.apache.fury.graalvm.CompatibleExample,\
org.apache.fury.graalvm.ScopedCompatibleExample,\
org.apache.fury.graalvm.record.RecordExample,\
org.apache.fury.graalvm.record.CompatibleRecordExample,\
org.apache.fury.graalvm.record.RecordExample2,\
org.apache.fury.graalvm.ThreadSafeExample,\
org.apache.fury.graalvm.CompatibleThreadSafeExample,\
org.apache.fury.graalvm.ProxyExample,\
org.apache.fury.graalvm.CollectionExample,\
org.apache.fury.graalvm.Benchmark
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import org.apache.fury.io.FuryReadableChannel;
import org.apache.fury.memory.MemoryBuffer;
import org.apache.fury.memory.MemoryUtils;
import org.apache.fury.resolver.ClassResolver;
import org.apache.fury.serializer.BufferCallback;
import org.apache.fury.util.LoaderBinding;
import org.apache.fury.util.LoaderBinding.StagingType;
Expand Down Expand Up @@ -65,8 +64,6 @@ public ThreadLocalFury(Function<ClassLoader, Fury> furyFactory) {
// in a process load some classes which is not cheap.
// 2. Make fury generate code at graalvm build time.
Fury fury = bindingThreadLocal.get().get();
ClassResolver._addGraalvmClassRegistry(
fury.getConfig().getConfigHash(), fury.getClassResolver());
}

@Override
Expand Down
11 changes: 10 additions & 1 deletion java/fury-core/src/main/java/org/apache/fury/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
/** Config for fury, all {@link Fury} related config can be found here. */
@SuppressWarnings({"rawtypes"})
public class Config implements Serializable {
private final String name;
private final Language language;
private final boolean trackingRef;
private final boolean basicTypesRefIgnored;
Expand Down Expand Up @@ -61,6 +62,7 @@ public class Config implements Serializable {
private final boolean deserializeNonexistentEnumValueAsNull;

public Config(FuryBuilder builder) {
name = builder.name;
language = builder.language;
trackingRef = builder.trackingRef;
basicTypesRefIgnored = !trackingRef || builder.basicTypesRefIgnored;
Expand Down Expand Up @@ -93,6 +95,11 @@ public Config(FuryBuilder builder) {
deserializeNonexistentEnumValueAsNull = builder.deserializeNonexistentEnumValueAsNull;
}

/** Returns the name for Fury serialization. */
public String getName() {
return name;
}

public Language getLanguage() {
return language;
}
Expand Down Expand Up @@ -257,7 +264,8 @@ public boolean equals(Object o) {
return false;
}
Config config = (Config) o;
return trackingRef == config.trackingRef
return name == config.name
&& trackingRef == config.trackingRef
&& basicTypesRefIgnored == config.basicTypesRefIgnored
&& stringRefIgnored == config.stringRefIgnored
&& timeRefIgnored == config.timeRefIgnored
Expand Down Expand Up @@ -286,6 +294,7 @@ public boolean equals(Object o) {
@Override
public int hashCode() {
return Objects.hash(
name,
language,
trackingRef,
basicTypesRefIgnored,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public final class FuryBuilder {
ENABLE_CLASS_REGISTRATION_FORCIBLY = "true".equals(flagValue) || "1".equals(flagValue);
}

String name;
boolean checkClassVersion = false;
Language language = Language.JAVA;
boolean trackingRef = false;
Expand Down Expand Up @@ -318,6 +319,12 @@ public FuryBuilder withScalaOptimizationEnabled(boolean enableScalaOptimization)
return this;
}

/** Set name for Fury serialization. */
public FuryBuilder withName(String name) {
this.name = name;
return this;
}

private void finish() {
if (classLoader == null) {
classLoader = Thread.currentThread().getContextClassLoader();
Expand Down
Loading

0 comments on commit 1f1528f

Please sign in to comment.