From b50f56da5b180d546c3f5fa9f5df91ebe0ddf99e Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Mon, 30 Jan 2023 16:36:51 +0100 Subject: [PATCH] ArC: fix InstanceHandle.close() to behave as specified in strict mode This means that it delegates to `destroy()` not only for `@Dependent` beans, but for all beans. To avoid breaking existing users, this is only done in the strict mode. --- .../java/io/quarkus/arc/InstanceHandle.java | 6 ++ .../src/test/resources/testng.xml | 6 -- .../io/quarkus/arc/test/ArcTestContainer.java | 3 +- .../destroy/InstanceHandleDestroyTest.java | 81 +++++++++++++++++++ 4 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/instance/destroy/InstanceHandleDestroyTest.java diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceHandle.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceHandle.java index 63bce6bf5fd68..dbca61638c8d1 100644 --- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceHandle.java +++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceHandle.java @@ -64,6 +64,12 @@ default InjectableBean getBean() { */ @Override default void close() { + // https://github.com/quarkusio/quarkus/issues/33665 + if (Arc.container().strictCompatibility()) { + destroy(); + return; + } + InjectableBean bean = getBean(); if (bean == null || Dependent.class.equals(bean.getScope())) { destroy(); diff --git a/independent-projects/arc/tcks/cdi-tck-runner/src/test/resources/testng.xml b/independent-projects/arc/tcks/cdi-tck-runner/src/test/resources/testng.xml index 844b4b621e59a..41731805956b1 100644 --- a/independent-projects/arc/tcks/cdi-tck-runner/src/test/resources/testng.xml +++ b/independent-projects/arc/tcks/cdi-tck-runner/src/test/resources/testng.xml @@ -100,12 +100,6 @@ - - - - - - diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/ArcTestContainer.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/ArcTestContainer.java index 6855a1c35a9b0..05b799d33fde4 100644 --- a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/ArcTestContainer.java +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/ArcTestContainer.java @@ -29,6 +29,7 @@ import org.junit.jupiter.api.extension.ExtensionContext; import io.quarkus.arc.Arc; +import io.quarkus.arc.ArcInitConfig; import io.quarkus.arc.ComponentsProvider; import io.quarkus.arc.ResourceReferenceProvider; import io.quarkus.arc.processor.AlternativePriorities; @@ -468,7 +469,7 @@ public void writeResource(Resource resource) throws IOException { .setContextClassLoader(testClassLoader); // Now we are ready to initialize Arc - Arc.initialize(); + Arc.initialize(ArcInitConfig.builder().setStrictCompatibility(strictCompatibility).build()); } catch (Throwable e) { if (shouldFail) { diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/instance/destroy/InstanceHandleDestroyTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/instance/destroy/InstanceHandleDestroyTest.java new file mode 100644 index 0000000000000..4cd5c46fc9198 --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/instance/destroy/InstanceHandleDestroyTest.java @@ -0,0 +1,81 @@ +package io.quarkus.arc.test.instance.destroy; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; + +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.context.Dependent; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.arc.Arc; +import io.quarkus.arc.InstanceHandle; +import io.quarkus.arc.test.ArcTestContainer; + +public class InstanceHandleDestroyTest { + @RegisterExtension + public ArcTestContainer container = new ArcTestContainer.Builder() + .beanClasses(MyDependentBean.class, MyAppScopedBean.class) + .strictCompatibility(true) + .build(); + + @Test + public void testDestroy() { + assertFalse(MyDependentBean.DESTROYED.get()); + try (InstanceHandle handle = Arc.container().instance(MyDependentBean.class)) { + assertNotNull(handle.get().toString()); + } + assertTrue(MyDependentBean.DESTROYED.get()); + + // normal-scoped + String oldId; + assertFalse(MyAppScopedBean.DESTROYED.get()); + try (InstanceHandle handle = Arc.container().instance(MyAppScopedBean.class)) { + assertNotNull(handle.get().toString()); + oldId = handle.get().getId(); + } + assertTrue(MyAppScopedBean.DESTROYED.get()); + + String newId = Arc.container().instance(MyAppScopedBean.class).get().getId(); + assertNotEquals(oldId, newId); + } + + @Dependent + static class MyDependentBean { + static final AtomicBoolean DESTROYED = new AtomicBoolean(false); + + @PreDestroy + void destroy() { + DESTROYED.set(true); + } + } + + @ApplicationScoped + static class MyAppScopedBean { + static final AtomicBoolean DESTROYED = new AtomicBoolean(false); + + String id; + + String getId() { + return id; + } + + @PostConstruct + void init() { + this.id = UUID.randomUUID().toString(); + } + + @PreDestroy + void destroy() { + DESTROYED.set(true); + } + } +}