From a8f5a342e526f3741f4935a3f644ad6878f00f3b Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Wed, 28 Jul 2021 11:45:30 +1000 Subject: [PATCH] Clear Avro cache on reload Fixes #18776 --- .../avro/deployment/AvroProcessor.java | 12 ++++++++ .../io/quarkus/avro/runtime/AvroRecorder.java | 29 +++++++++++++++++++ .../graal/AvroSubstitutions.java | 2 +- 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 extensions/avro/runtime/src/main/java/io/quarkus/avro/runtime/AvroRecorder.java rename extensions/avro/runtime/src/main/java/io/quarkus/avro/{ => runtime}/graal/AvroSubstitutions.java (99%) diff --git a/extensions/avro/deployment/src/main/java/io/quarkus/avro/deployment/AvroProcessor.java b/extensions/avro/deployment/src/main/java/io/quarkus/avro/deployment/AvroProcessor.java index d1f96c6f6b2804..03857b6cb0c75a 100644 --- a/extensions/avro/deployment/src/main/java/io/quarkus/avro/deployment/AvroProcessor.java +++ b/extensions/avro/deployment/src/main/java/io/quarkus/avro/deployment/AvroProcessor.java @@ -7,15 +7,27 @@ import org.jboss.jandex.AnnotationTarget; import org.jboss.jandex.DotName; +import io.quarkus.avro.runtime.AvroRecorder; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.ExecutionTime; +import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.CombinedIndexBuildItem; +import io.quarkus.deployment.builditem.LaunchModeBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageConfigBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageSystemPropertyBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; public class AvroProcessor { + @BuildStep + @Record(ExecutionTime.STATIC_INIT) + void clearCaches(AvroRecorder recorder, LaunchModeBuildItem launchModeBuildItem) { + if (launchModeBuildItem.getLaunchMode().isDevOrTest()) { + recorder.clearStaticCaches(); + } + } + @BuildStep public void build(CombinedIndexBuildItem indexBuildItem, BuildProducer reflectiveClass, diff --git a/extensions/avro/runtime/src/main/java/io/quarkus/avro/runtime/AvroRecorder.java b/extensions/avro/runtime/src/main/java/io/quarkus/avro/runtime/AvroRecorder.java new file mode 100644 index 00000000000000..860110da4ecc66 --- /dev/null +++ b/extensions/avro/runtime/src/main/java/io/quarkus/avro/runtime/AvroRecorder.java @@ -0,0 +1,29 @@ +package io.quarkus.avro.runtime; + +import java.lang.reflect.Field; +import java.util.Map; + +import org.apache.avro.specific.SpecificData; +import org.jboss.logging.Logger; + +import io.quarkus.runtime.annotations.Recorder; + +@Recorder +public class AvroRecorder { + + private static final Logger log = Logger.getLogger(AvroRecorder.class); + + public void clearStaticCaches() { + try { + Field instanceField = SpecificData.class.getDeclaredField("INSTANCE"); + instanceField.setAccessible(true); + SpecificData data = (SpecificData) instanceField.get(null); + Field classCache = SpecificData.class.getDeclaredField("classCache"); + classCache.setAccessible(true); + Map classCacheMap = (Map) classCache.get(data); + classCacheMap.clear(); + } catch (Throwable t) { + log.error("Failed to clear Avro cache", t); + } + } +} diff --git a/extensions/avro/runtime/src/main/java/io/quarkus/avro/graal/AvroSubstitutions.java b/extensions/avro/runtime/src/main/java/io/quarkus/avro/runtime/graal/AvroSubstitutions.java similarity index 99% rename from extensions/avro/runtime/src/main/java/io/quarkus/avro/graal/AvroSubstitutions.java rename to extensions/avro/runtime/src/main/java/io/quarkus/avro/runtime/graal/AvroSubstitutions.java index d329f152e49d87..3b6b17bf5cedb6 100644 --- a/extensions/avro/runtime/src/main/java/io/quarkus/avro/graal/AvroSubstitutions.java +++ b/extensions/avro/runtime/src/main/java/io/quarkus/avro/runtime/graal/AvroSubstitutions.java @@ -1,4 +1,4 @@ -package io.quarkus.avro.graal; +package io.quarkus.avro.runtime.graal; import java.lang.reflect.Constructor; import java.util.HashMap;