diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Beans.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Beans.java index 199e040fb3aaf..f6200b874084f 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Beans.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Beans.java @@ -64,9 +64,11 @@ private static ScopeInfo inheritScope(ClassInfo beanClass, BeanDeployment beanDe } for (AnnotationInstance annotation : beanDeployment.getAnnotationStore().getAnnotations(classFromIndex)) { ScopeInfo scopeAnnotation = beanDeployment.getScope(annotation.name()); - if (scopeAnnotation != null && scopeAnnotation.declaresInherited()) { - // found some scope, return - return scopeAnnotation; + if (scopeAnnotation != null) { + // found some scope, return it if it's inherited + // if it isn't inherited, it still prevents the bean class + // from inheriting another scope from a further superclass + return scopeAnnotation.declaresInherited() ? scopeAnnotation : null; } } superClassName = classFromIndex.superName(); 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 fdc566c65a169..387054bf40c3e 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 @@ -55,11 +55,6 @@ - - - - - diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/bean/scope/ScopeInheritanceTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/bean/scope/ScopeInheritanceTest.java new file mode 100644 index 0000000000000..94c05b8f04658 --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/bean/scope/ScopeInheritanceTest.java @@ -0,0 +1,76 @@ +package io.quarkus.arc.test.bean.scope; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.context.NormalScope; +import jakarta.enterprise.context.RequestScoped; +import jakarta.enterprise.inject.Stereotype; +import jakarta.enterprise.inject.spi.Bean; +import jakarta.enterprise.inject.spi.BeanManager; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.arc.Arc; +import io.quarkus.arc.test.ArcTestContainer; + +public class ScopeInheritanceTest { + @RegisterExtension + ArcTestContainer container = new ArcTestContainer(MyScope.class, MyStereotype.class, MyBean1.class, MyBean2.class); + + @Test + public void nonInheritedScopeOnDirectSuperclass() { + BeanManager bm = Arc.container().beanManager(); + Bean bean = (Bean) bm.resolve(bm.getBeans(MyBean1.class)); + assertEquals(Dependent.class, bean.getScope()); + } + + @Test + public void inheritedScopeOnDirectSuperclass() { + BeanManager bm = Arc.container().beanManager(); + Bean bean = (Bean) bm.resolve(bm.getBeans(MyBean2.class)); + assertEquals(RequestScoped.class, bean.getScope()); + } + + @Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD }) + @Retention(RetentionPolicy.RUNTIME) + @NormalScope + @interface MyScope { + } + + // just a bean defining annotation + @Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD }) + @Retention(RetentionPolicy.RUNTIME) + @Stereotype + @interface MyStereotype { + } + + @MyStereotype + static class MyBean1 extends DirectSuperclassWithNonInheritedScope { + } + + @MyStereotype + static class MyBean2 extends DirectSuperclassWithInheritedScope { + } + + // `MyScope` is not `@Inherited`, so `MyBean1` will not inherit it, but it will + // also prevent inheriting `@ApplicationScoped` from `IndirectSuperclass` + @MyScope + static class DirectSuperclassWithNonInheritedScope extends IndirectSuperclass { + } + + @RequestScoped + static class DirectSuperclassWithInheritedScope extends IndirectSuperclass { + } + + @ApplicationScoped + static class IndirectSuperclass { + } +}