Skip to content

Commit a1909e9

Browse files
zhfenggastaldi
authored andcommitted
Lambda function serialization (#17)
* do lambda capuring class in duringSetup * update ResourceLambda to use ByteArrayOutputStream * remove serialization-config.json
1 parent f5ed21c commit a1909e9

File tree

4 files changed

+35
-42
lines changed

4 files changed

+35
-42
lines changed

core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageAutoFeatureStep.java

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ public class NativeImageAutoFeatureStep {
9494
static final String RUNTIME_REFLECTION = RuntimeReflection.class.getName();
9595
static final String JNI_RUNTIME_ACCESS = "com.oracle.svm.core.jni.JNIRuntimeAccess";
9696
static final String BEFORE_ANALYSIS_ACCESS = Feature.BeforeAnalysisAccess.class.getName();
97+
static final String DURING_SETUP_ACCESS = Feature.DuringSetupAccess.class.getName();
9798
static final String DYNAMIC_PROXY_REGISTRY = "com.oracle.svm.core.jdk.proxy.DynamicProxyRegistry";
9899
static final String LEGACY_LOCALIZATION_FEATURE = "com.oracle.svm.core.jdk.LocalizationFeature";
99100
static final String LOCALIZATION_FEATURE = "com.oracle.svm.core.jdk.localization.LocalizationFeature";
@@ -143,7 +144,27 @@ public void write(String s, byte[] bytes) {
143144
Object.class.getName(), Feature.class.getName());
144145
file.addAnnotation("com.oracle.svm.core.annotate.AutomaticFeature");
145146

146-
//MethodCreator afterReg = file.getMethodCreator("afterRegistration", void.class, "org.graalvm.nativeimage.Feature$AfterRegistrationAccess");
147+
MethodCreator duringSetup = file.getMethodCreator("duringSetup", "V", DURING_SETUP_ACCESS);
148+
// Register Lambda Capturing Types
149+
if (!lambdaCapturingTypeBuildItems.isEmpty()) {
150+
ResultHandle runtimeSerializationSupportSingleton = duringSetup.invokeStaticMethod(IMAGE_SINGLETONS_LOOKUP,
151+
duringSetup.loadClassFromTCCL("org.graalvm.nativeimage.impl.RuntimeSerializationSupport"));
152+
ResultHandle configAlwaysTrue = duringSetup.invokeStaticMethod(CONFIGURATION_ALWAYS_TRUE);
153+
154+
for (LambdaCapturingTypeBuildItem i : lambdaCapturingTypeBuildItems) {
155+
TryBlock tryBlock = duringSetup.tryBlock();
156+
157+
tryBlock.invokeInterfaceMethod(REGISTER_LAMBDA_CAPTURING_CLASS, runtimeSerializationSupportSingleton,
158+
configAlwaysTrue,
159+
tryBlock.load(i.getClassName()));
160+
161+
CatchBlockCreator catchBlock = tryBlock.addCatch(Throwable.class);
162+
catchBlock.invokeVirtualMethod(ofMethod(Throwable.class, "printStackTrace", void.class),
163+
catchBlock.getCaughtException());
164+
}
165+
}
166+
duringSetup.returnValue(null);
167+
147168
MethodCreator beforeAn = file.getMethodCreator("beforeAnalysis", "V", BEFORE_ANALYSIS_ACCESS);
148169
TryBlock overallCatch = beforeAn.tryBlock();
149170
//TODO: at some point we are going to need to break this up, as if it get too big it will hit the method size limit
@@ -312,25 +333,6 @@ public void write(String s, byte[] bytes) {
312333
overallCatch.load(i.serviceDescriptorFile()));
313334
}
314335

315-
// Register Lambda Capturing Types
316-
if (!lambdaCapturingTypeBuildItems.isEmpty()) {
317-
ResultHandle runtimeSerializationSupportSingleton = overallCatch.invokeStaticMethod(IMAGE_SINGLETONS_LOOKUP,
318-
overallCatch.loadClassFromTCCL("org.graalvm.nativeimage.impl.RuntimeSerializationSupport"));
319-
ResultHandle configAlwaysTrue = overallCatch.invokeStaticMethod(CONFIGURATION_ALWAYS_TRUE);
320-
321-
for (LambdaCapturingTypeBuildItem i : lambdaCapturingTypeBuildItems) {
322-
TryBlock tryBlock = overallCatch.tryBlock();
323-
324-
tryBlock.invokeInterfaceMethod(REGISTER_LAMBDA_CAPTURING_CLASS, runtimeSerializationSupportSingleton,
325-
configAlwaysTrue,
326-
tryBlock.load(i.getClassName()));
327-
328-
CatchBlockCreator catchBlock = tryBlock.addCatch(Throwable.class);
329-
catchBlock.invokeVirtualMethod(ofMethod(Throwable.class, "printStackTrace", void.class),
330-
catchBlock.getCaughtException());
331-
}
332-
}
333-
334336
if (!resourceBundles.isEmpty()) {
335337
AssignableResultHandle registerMethod = overallCatch.createVariable(Method.class);
336338
AssignableResultHandle locClass = overallCatch.createVariable(Class.class);
Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,41 @@
11
package io.quarkus.it.rest;
22

3-
import java.io.FileInputStream;
4-
import java.io.FileOutputStream;
3+
import java.io.ByteArrayInputStream;
4+
import java.io.ByteArrayOutputStream;
55
import java.io.IOException;
66
import java.io.ObjectInputStream;
77
import java.io.ObjectOutputStream;
8+
import java.io.Serializable;
89
import java.lang.invoke.SerializedLambda;
910
import java.util.Comparator;
1011

1112
import io.quarkus.runtime.annotations.RegisterForReflection;
1213

1314
/**
14-
* This class is registering itself for lambda capturing
15+
* This class is registering for lambda capturing
1516
*/
1617
@RegisterForReflection(lambdaCapturingTypes = "java.util.Comparator", targets = {
1718
SerializedLambda.class, SerializableDoubleFunction.class }, serialization = true)
1819
public class ResourceLambda {
19-
private static final String file = "target/serialized.txt";
2020

2121
public Class<?> getLambdaFuncClass(Integer n) throws IOException, ClassNotFoundException {
2222
SerializableDoubleFunction func = new SerializableDoubleFunction(n);
2323
Comparator<Integer> comp = Comparator.comparingDouble(func);
24-
serializeObject(comp);
25-
return deserializeObject().getClass();
24+
25+
ByteArrayOutputStream out = new ByteArrayOutputStream();
26+
serializeObject(out, (Serializable) comp);
27+
return deserializeObject(out).getClass();
2628
}
2729

28-
private void serializeObject(Object o) throws IOException {
29-
FileOutputStream out = new FileOutputStream(file);
30-
ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);
30+
private void serializeObject(ByteArrayOutputStream byteArrayOutputStream, Serializable o) throws IOException {
31+
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
3132
objectOutputStream.writeObject(o);
3233
objectOutputStream.close();
3334
}
3435

35-
private Object deserializeObject() throws IOException, ClassNotFoundException {
36-
FileInputStream in = new FileInputStream(file);
37-
ObjectInputStream objectInputStream = new ObjectInputStream(in);
36+
private Object deserializeObject(ByteArrayOutputStream byteArrayOutputStream) throws IOException, ClassNotFoundException {
37+
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
38+
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
3839
return objectInputStream.readObject();
3940
}
4041
}

integration-tests/main/src/main/resources/application.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ quarkus.native.resources.excludes = **/unwanted.*
5252

5353
quarkus.log.metrics.enabled=true
5454

55-
#quarkus.native.additional-build-args =-H:ReflectionConfigurationFiles=reflection-config.json,-H:SerializationConfigurationResources=serialization-config.json
5655
quarkus.native.additional-build-args =-H:ReflectionConfigurationFiles=reflection-config.json
5756
quarkus.class-loading.removed-resources."io.quarkus\:quarkus-integration-test-shared-library"=io/quarkus/it/shared/RemovedResource.class
5857
quarkus.class-loading.removed-resources."io.quarkus\:quarkus-integration-test-main"=io/quarkus/it/rest/RemovedJaxRsApplication.class

integration-tests/main/src/main/resources/serialization-config.json

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)