Skip to content

Commit

Permalink
ArC: fix searching for inherited scopes
Browse files Browse the repository at this point in the history
The CDI specification mandates that if a superclass of a bean declares
a scope annotation, scope annotations from further superclasses are
not inherited. This holds even if the annotation is not `@Inherited`.
This commit fixes searching for inherited scopes to honor this.
  • Loading branch information
Ladicek committed May 19, 2023
1 parent 087b2c4 commit 986ac03
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,6 @@
<exclude name="testDestroyForSameCreationalContextOnly"/>
</methods>
</class>
<class name="org.jboss.cdi.tck.tests.definition.scope.ScopeDefinitionTest">
<methods>
<exclude name="testScopeTypeDeclaredInheritedIsBlockedByIntermediateScopeTypeNotMarkedInherited"/>
</methods>
</class>
<class name="org.jboss.cdi.tck.tests.interceptors.definition.inheritance.InterceptorBindingInheritanceTest">
<methods>
<exclude name="testInterceptorBindingDirectlyInheritedFromManagedBean"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -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<MyBean1> bean = (Bean<MyBean1>) bm.resolve(bm.getBeans(MyBean1.class));
assertEquals(Dependent.class, bean.getScope());
}

@Test
public void inheritedScopeOnDirectSuperclass() {
BeanManager bm = Arc.container().beanManager();
Bean<MyBean2> bean = (Bean<MyBean2>) 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 {
}
}

0 comments on commit 986ac03

Please sign in to comment.