From e03d1779ae0f3568b9279ba95f04e9ffabac5f94 Mon Sep 17 00:00:00 2001 From: Severin Gehwolf Date: Mon, 27 Feb 2023 16:37:27 +0100 Subject: [PATCH] Runtime init the cleaner instance in ResourceCleaner Inject an accessor for the ResourceCleaner.CLEANER static variable so that the associated cleaner won't get initialized at build time. Closes: #31440 --- .../graal/ResourceCleanerReplacement.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 extensions/resteasy-classic/rest-client/runtime/src/main/java/io/quarkus/restclient/runtime/graal/ResourceCleanerReplacement.java diff --git a/extensions/resteasy-classic/rest-client/runtime/src/main/java/io/quarkus/restclient/runtime/graal/ResourceCleanerReplacement.java b/extensions/resteasy-classic/rest-client/runtime/src/main/java/io/quarkus/restclient/runtime/graal/ResourceCleanerReplacement.java new file mode 100644 index 00000000000000..f3bee92eaca622 --- /dev/null +++ b/extensions/resteasy-classic/rest-client/runtime/src/main/java/io/quarkus/restclient/runtime/graal/ResourceCleanerReplacement.java @@ -0,0 +1,45 @@ +package io.quarkus.restclient.runtime.graal; + +import java.lang.ref.Cleaner; + +import com.oracle.svm.core.annotate.Alias; +import com.oracle.svm.core.annotate.InjectAccessors; +import com.oracle.svm.core.annotate.TargetClass; + +/** + * For GraalVM native we runtime-inject the Cleaner instance via an injected + * accessor. This awkward pattern over say, the initialize on demand holder + * pattern, is necessary so that the Graal compiler doesn't inline the accessor + * itself. + */ +@TargetClass(className = "org.jboss.resteasy.spi.ResourceCleaner") +public final class ResourceCleanerReplacement { + + @Alias + @InjectAccessors(CleanerAccessor.class) // + private static Cleaner CLEANER; + + static class CleanerAccessor { + private static volatile Cleaner INSTANCE; + + static Cleaner get() { + Cleaner result = INSTANCE; + if (result == null) { + // lazily initialize instance + result = initializeOnce(); + } + return result; + } + + private static synchronized Cleaner initializeOnce() { + Cleaner result = INSTANCE; + if (result == null) { + // double checked locking is ok as INSTANCE is volatile + result = INSTANCE = Cleaner.create(); + } + return result; + } + + } + +}