Skip to content

Commit 30f34f6

Browse files
authored
Merge pull request #20232 from zakkak/fix-20226
Add GraalVM 21.3 compatibility support for resource registration
2 parents 47412a1 + b5361d8 commit 30f34f6

File tree

1 file changed

+75
-39
lines changed

1 file changed

+75
-39
lines changed

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

Lines changed: 75 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,13 @@ public class NativeImageAutoFeatureStep {
7272
private static final MethodDescriptor RERUN_INITIALIZATION = ofMethod(
7373
"org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport",
7474
"rerunInitialization", void.class, Class.class, String.class);
75-
private static final MethodDescriptor RESOURCES_REGISTRY_ADD_RESOURCES = ofMethod(
76-
"com.oracle.svm.core.configure.ResourcesRegistry",
77-
"addResources", void.class, String.class);
78-
private static final MethodDescriptor RESOURCES_REGISTRY_IGNORE_RESOURCES = ofMethod(
79-
"com.oracle.svm.core.configure.ResourcesRegistry",
80-
"ignoreResources", void.class, String.class);
75+
private static final MethodDescriptor LOOKUP_METHOD = ofMethod(
76+
"com.oracle.svm.util.ReflectionUtil",
77+
"lookupMethod", Method.class, Class.class, String.class, Class[].class);
78+
private static final MethodDescriptor FOR_NAME = ofMethod(
79+
Class.class, "forName", Class.class, String.class, boolean.class, ClassLoader.class);
80+
private static final MethodDescriptor INVOKE = ofMethod(
81+
Method.class, "invoke", Object.class, Object.class, Object[].class);
8182
static final String RUNTIME_REFLECTION = RuntimeReflection.class.getName();
8283
static final String JNI_RUNTIME_ACCESS = "com.oracle.svm.core.jni.JNIRuntimeAccess";
8384
static final String BEFORE_ANALYSIS_ACCESS = Feature.BeforeAnalysisAccess.class.getName();
@@ -230,16 +231,63 @@ public void write(String s, byte[] bytes) {
230231
ResultHandle resourcesRegistrySingleton = overallCatch.invokeStaticMethod(IMAGE_SINGLETONS_LOOKUP,
231232
overallCatch.loadClass("com.oracle.svm.core.configure.ResourcesRegistry"));
232233
TryBlock tc = overallCatch.tryBlock();
234+
235+
ResultHandle currentThread = tc.invokeStaticMethod(ofMethod(Thread.class, "currentThread", Thread.class));
236+
ResultHandle tccl = tc.invokeVirtualMethod(ofMethod(Thread.class, "getContextClassLoader", ClassLoader.class),
237+
currentThread);
238+
AssignableResultHandle resourcesArgTypes = tc.createVariable(Class[].class);
239+
AssignableResultHandle resourcesArgs = tc.createVariable(Object[].class);
240+
AssignableResultHandle argsIndex = tc.createVariable(int.class);
241+
242+
BranchResult graalVm21_3Test = tc.ifGreaterEqualZero(
243+
tc.invokeVirtualMethod(VERSION_COMPARE_TO,
244+
tc.invokeStaticMethod(VERSION_CURRENT),
245+
tc.marshalAsArray(int.class, tc.load(21), tc.load(3))));
246+
/* GraalVM >= 21.3 */
247+
BytecodeCreator greaterThan21_2 = graalVm21_3Test.trueBranch();
248+
ResultHandle argTypes = greaterThan21_2.newArray(Class.class, greaterThan21_2.load(2));
249+
ResultHandle configurationConditionClass = greaterThan21_2.invokeStaticMethod(FOR_NAME,
250+
greaterThan21_2.load("org.graalvm.nativeimage.impl.ConfigurationCondition"),
251+
greaterThan21_2.load(false), tccl);
252+
greaterThan21_2.writeArrayValue(argTypes, 0, configurationConditionClass);
253+
greaterThan21_2.writeArrayValue(argTypes, 1, greaterThan21_2.loadClass(String.class));
254+
greaterThan21_2.assign(resourcesArgTypes, argTypes);
255+
ResultHandle args = greaterThan21_2.newArray(Object.class, greaterThan21_2.load(2));
256+
ResultHandle alwaysTrueMethod = greaterThan21_2.invokeStaticMethod(LOOKUP_METHOD,
257+
configurationConditionClass,
258+
greaterThan21_2.load("alwaysTrue"),
259+
greaterThan21_2.newArray(Class.class, greaterThan21_2.load(0)));
260+
ResultHandle alwaysTrueResult = greaterThan21_2.invokeVirtualMethod(INVOKE,
261+
alwaysTrueMethod, greaterThan21_2.loadNull(),
262+
greaterThan21_2.newArray(Object.class, greaterThan21_2.load(0)));
263+
greaterThan21_2.writeArrayValue(args, 0, alwaysTrueResult);
264+
greaterThan21_2.assign(resourcesArgs, args);
265+
greaterThan21_2.assign(argsIndex, greaterThan21_2.load(1));
266+
267+
/* GraalVM < 21.3 */
268+
BytecodeCreator smallerThan21_3 = graalVm21_3Test.falseBranch();
269+
argTypes = smallerThan21_3.newArray(Class.class, smallerThan21_3.load(1));
270+
smallerThan21_3.writeArrayValue(argTypes, 0, smallerThan21_3.loadClass(String.class));
271+
smallerThan21_3.assign(resourcesArgTypes, argTypes);
272+
args = smallerThan21_3.newArray(Object.class, smallerThan21_3.load(1));
273+
smallerThan21_3.assign(resourcesArgs, args);
274+
smallerThan21_3.assign(argsIndex, smallerThan21_3.load(0));
275+
276+
ResultHandle ignoreResourcesMethod = tc.invokeStaticMethod(LOOKUP_METHOD,
277+
tc.loadClass("com.oracle.svm.core.configure.ResourcesRegistry"),
278+
tc.load("ignoreResources"), resourcesArgTypes);
279+
ResultHandle addResourcesMethod = tc.invokeStaticMethod(LOOKUP_METHOD,
280+
tc.loadClass("com.oracle.svm.core.configure.ResourcesRegistry"),
281+
tc.load("addResources"), resourcesArgTypes);
282+
233283
for (NativeImageResourcePatternsBuildItem resourcePatternsItem : resourcePatterns) {
234284
for (String pattern : resourcePatternsItem.getExcludePatterns()) {
235-
tc.invokeInterfaceMethod(RESOURCES_REGISTRY_IGNORE_RESOURCES, resourcesRegistrySingleton,
236-
overallCatch.load(pattern));
285+
tc.writeArrayValue(resourcesArgs, argsIndex, tc.load(pattern));
286+
tc.invokeVirtualMethod(INVOKE, ignoreResourcesMethod, resourcesRegistrySingleton, resourcesArgs);
237287
}
238288
for (String pattern : resourcePatternsItem.getIncludePatterns()) {
239-
tc.invokeInterfaceMethod(
240-
RESOURCES_REGISTRY_ADD_RESOURCES,
241-
resourcesRegistrySingleton,
242-
tc.load(pattern));
289+
tc.writeArrayValue(resourcesArgs, argsIndex, tc.load(pattern));
290+
tc.invokeVirtualMethod(INVOKE, addResourcesMethod, resourcesRegistrySingleton, resourcesArgs);
243291
}
244292
}
245293
CatchBlockCreator cc = tc.addCatch(Throwable.class);
@@ -538,39 +586,30 @@ private MethodDescriptor createRegisterSerializationForClassMethod(ClassCreator
538586
ofMethod(Thread.class, "getContextClassLoader", ClassLoader.class),
539587
currentThread);
540588

541-
MethodDescriptor forNameMethodDescriptor = ofMethod(Class.class, "forName", Class.class, String.class, boolean.class,
542-
ClassLoader.class);
543-
544-
MethodDescriptor lookupMethod = ofMethod("com.oracle.svm.util.ReflectionUtil", "lookupMethod", Method.class,
545-
Class.class, String.class,
546-
Class[].class);
547-
MethodDescriptor invokeMethodDescriptor = ofMethod(Method.class, "invoke", Object.class, Object.class,
548-
Object[].class);
549-
550589
BranchResult graalVm21_3Test = tc.ifGreaterEqualZero(
551590
tc.invokeVirtualMethod(VERSION_COMPARE_TO, tc.invokeStaticMethod(VERSION_CURRENT),
552591
tc.marshalAsArray(int.class, tc.load(21), tc.load(3))));
553592

554593
BytecodeCreator greaterThan21_3 = graalVm21_3Test.trueBranch();
555-
ResultHandle runtimeSerializationClass = greaterThan21_3.invokeStaticMethod(forNameMethodDescriptor,
594+
ResultHandle runtimeSerializationClass = greaterThan21_3.invokeStaticMethod(FOR_NAME,
556595
greaterThan21_3.load("org.graalvm.nativeimage.hosted.RuntimeSerialization"),
557596
greaterThan21_3.load(false), tccl);
558597
ResultHandle registerArgTypes = greaterThan21_3.newArray(Class.class, greaterThan21_3.load(1));
559598
greaterThan21_3.writeArrayValue(registerArgTypes, 0, greaterThan21_3.loadClass(Class[].class));
560-
ResultHandle registerLookupMethod = greaterThan21_3.invokeStaticMethod(lookupMethod, runtimeSerializationClass,
599+
ResultHandle registerLookupMethod = greaterThan21_3.invokeStaticMethod(LOOKUP_METHOD, runtimeSerializationClass,
561600
greaterThan21_3.load("register"), registerArgTypes);
562601
ResultHandle registerArgs = greaterThan21_3.newArray(Object.class, greaterThan21_3.load(1));
563602
ResultHandle classesToRegister = greaterThan21_3.newArray(Class.class, greaterThan21_3.load(1));
564603
greaterThan21_3.writeArrayValue(classesToRegister, 0, clazz);
565604
greaterThan21_3.writeArrayValue(registerArgs, 0, classesToRegister);
566-
greaterThan21_3.invokeVirtualMethod(invokeMethodDescriptor, registerLookupMethod,
605+
greaterThan21_3.invokeVirtualMethod(INVOKE, registerLookupMethod,
567606
greaterThan21_3.loadNull(), registerArgs);
568607
greaterThan21_3.returnValue(null);
569608

570-
ResultHandle serializationRegistryClass = tc.invokeStaticMethod(forNameMethodDescriptor,
609+
ResultHandle serializationRegistryClass = tc.invokeStaticMethod(FOR_NAME,
571610
tc.load("com.oracle.svm.core.jdk.serialize.SerializationRegistry"),
572611
tc.load(false), tccl);
573-
ResultHandle addReflectionsClass = tc.invokeStaticMethod(forNameMethodDescriptor,
612+
ResultHandle addReflectionsClass = tc.invokeStaticMethod(FOR_NAME,
574613
tc.load("com.oracle.svm.reflect.serialize.hosted.SerializationFeature"),
575614
tc.load(false), tccl);
576615

@@ -581,39 +620,36 @@ private MethodDescriptor createRegisterSerializationForClassMethod(ClassCreator
581620
ResultHandle addReflectionsLookupArgs = tc.newArray(Class.class, tc.load(2));
582621
tc.writeArrayValue(addReflectionsLookupArgs, 0, tc.loadClass(Class.class));
583622
tc.writeArrayValue(addReflectionsLookupArgs, 1, tc.loadClass(Class.class));
584-
ResultHandle addReflectionsLookupMethod = tc.invokeStaticMethod(lookupMethod, addReflectionsClass,
623+
ResultHandle addReflectionsLookupMethod = tc.invokeStaticMethod(LOOKUP_METHOD, addReflectionsClass,
585624
tc.load("addReflections"), addReflectionsLookupArgs);
586625

587626
ResultHandle reflectionFactory = tc.invokeStaticMethod(
588627
ofMethod("sun.reflect.ReflectionFactory", "getReflectionFactory", "sun.reflect.ReflectionFactory"));
589628

590629
AssignableResultHandle newSerializationConstructor = tc.createVariable(Constructor.class);
591630

592-
ResultHandle externalizableClass = tc.invokeStaticMethod(
593-
forNameMethodDescriptor,
594-
tc.load("java.io.Externalizable"), tc.load(false), tccl);
631+
ResultHandle externalizableClass = tc.invokeStaticMethod(FOR_NAME, tc.load("java.io.Externalizable"), tc.load(false),
632+
tccl);
595633

596634
BranchResult isExternalizable = tc
597635
.ifTrue(tc.invokeVirtualMethod(ofMethod(Class.class, "isAssignableFrom", boolean.class, Class.class),
598636
externalizableClass, clazz));
599637
BytecodeCreator ifIsExternalizable = isExternalizable.trueBranch();
600638

601639
ResultHandle array1 = ifIsExternalizable.newArray(Class.class, tc.load(1));
602-
ResultHandle classClass = ifIsExternalizable.invokeStaticMethod(
603-
forNameMethodDescriptor,
640+
ResultHandle classClass = ifIsExternalizable.invokeStaticMethod(FOR_NAME,
604641
ifIsExternalizable.load("java.lang.Class"), ifIsExternalizable.load(false), tccl);
605642
ifIsExternalizable.writeArrayValue(array1, 0, classClass);
606643

607-
ResultHandle externalizableLookupMethod = ifIsExternalizable.invokeStaticMethod(
608-
lookupMethod,
644+
ResultHandle externalizableLookupMethod = ifIsExternalizable.invokeStaticMethod(LOOKUP_METHOD,
609645
ifIsExternalizable.loadClass(ObjectStreamClass.class), ifIsExternalizable.load("getExternalizableConstructor"),
610646
array1);
611647

612648
ResultHandle array2 = ifIsExternalizable.newArray(Object.class, tc.load(1));
613649
ifIsExternalizable.writeArrayValue(array2, 0, clazz);
614650

615651
ResultHandle externalizableConstructor = ifIsExternalizable.invokeVirtualMethod(
616-
invokeMethodDescriptor, externalizableLookupMethod, ifIsExternalizable.loadNull(), array2);
652+
INVOKE, externalizableLookupMethod, ifIsExternalizable.loadNull(), array2);
617653

618654
ResultHandle externalizableConstructorClass = ifIsExternalizable.invokeVirtualMethod(
619655
ofMethod(Constructor.class, "getDeclaringClass", Class.class),
@@ -622,7 +658,7 @@ private MethodDescriptor createRegisterSerializationForClassMethod(ClassCreator
622658
ResultHandle addReflectionsArgs1 = ifIsExternalizable.newArray(Class.class, tc.load(2));
623659
ifIsExternalizable.writeArrayValue(addReflectionsArgs1, 0, clazz);
624660
ifIsExternalizable.writeArrayValue(addReflectionsArgs1, 1, externalizableConstructorClass);
625-
ifIsExternalizable.invokeVirtualMethod(invokeMethodDescriptor, addReflectionsLookupMethod,
661+
ifIsExternalizable.invokeVirtualMethod(INVOKE, addReflectionsLookupMethod,
626662
ifIsExternalizable.loadNull(), addReflectionsArgs1);
627663

628664
ifIsExternalizable.returnValue(null);
@@ -655,11 +691,11 @@ private MethodDescriptor createRegisterSerializationForClassMethod(ClassCreator
655691
newSerializationConstructor);
656692

657693
ResultHandle getConstructorAccessor = tc.invokeStaticMethod(
658-
lookupMethod, tc.loadClass(Constructor.class), tc.load("getConstructorAccessor"),
694+
LOOKUP_METHOD, tc.loadClass(Constructor.class), tc.load("getConstructorAccessor"),
659695
tc.newArray(Class.class, tc.load(0)));
660696

661697
ResultHandle accessor = tc.invokeVirtualMethod(
662-
invokeMethodDescriptor, getConstructorAccessor, newSerializationConstructor,
698+
INVOKE, getConstructorAccessor, newSerializationConstructor,
663699
tc.newArray(Object.class, tc.load(0)));
664700

665701
tc.invokeVirtualMethod(
@@ -669,7 +705,7 @@ private MethodDescriptor createRegisterSerializationForClassMethod(ClassCreator
669705
ResultHandle addReflectionsArgs2 = tc.newArray(Class.class, tc.load(2));
670706
tc.writeArrayValue(addReflectionsArgs2, 0, clazz);
671707
tc.writeArrayValue(addReflectionsArgs2, 1, newSerializationConstructorClass);
672-
tc.invokeVirtualMethod(invokeMethodDescriptor, addReflectionsLookupMethod, tc.loadNull(), addReflectionsArgs2);
708+
tc.invokeVirtualMethod(INVOKE, addReflectionsLookupMethod, tc.loadNull(), addReflectionsArgs2);
673709

674710
addSerializationForClass.returnValue(null);
675711

0 commit comments

Comments
 (0)