diff --git a/impl/src/main/java/org/jboss/weld/annotated/enhanced/jlr/EnhancedAnnotatedTypeImpl.java b/impl/src/main/java/org/jboss/weld/annotated/enhanced/jlr/EnhancedAnnotatedTypeImpl.java index bda1bc1bba8..322b94dc5c0 100644 --- a/impl/src/main/java/org/jboss/weld/annotated/enhanced/jlr/EnhancedAnnotatedTypeImpl.java +++ b/impl/src/main/java/org/jboss/weld/annotated/enhanced/jlr/EnhancedAnnotatedTypeImpl.java @@ -34,7 +34,6 @@ import jakarta.enterprise.inject.spi.AnnotatedConstructor; import jakarta.enterprise.inject.spi.AnnotatedField; import jakarta.enterprise.inject.spi.AnnotatedMethod; -import jakarta.inject.Inject; import org.jboss.weld.annotated.enhanced.ConstructorSignature; import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedConstructor; @@ -45,8 +44,6 @@ import org.jboss.weld.annotated.slim.AnnotatedTypeIdentifier; import org.jboss.weld.annotated.slim.SlimAnnotatedType; import org.jboss.weld.annotated.slim.backed.BackedAnnotatedType; -import org.jboss.weld.interceptor.spi.model.InterceptionType; -import org.jboss.weld.interceptor.util.InterceptionTypeRegistry; import org.jboss.weld.resources.ClassTransformer; import org.jboss.weld.util.collections.ImmutableSet; import org.jboss.weld.util.collections.ListMultimap; @@ -71,17 +68,6 @@ */ public class EnhancedAnnotatedTypeImpl extends AbstractEnhancedAnnotated> implements EnhancedAnnotatedType { - private static final Set> MAPPED_METHOD_ANNOTATIONS; - - static { - Set> annotations = new HashSet>(); - for (InterceptionType interceptionType : InterceptionTypeRegistry.getSupportedInterceptionTypes()) { - annotations.add(InterceptionTypeRegistry.getAnnotationClass(interceptionType)); - } - annotations.add(Inject.class); - MAPPED_METHOD_ANNOTATIONS = ImmutableSet.copyOf(annotations); - } - @SuppressFBWarnings("unchecked") private static final Set> MAPPED_METHOD_PARAMETER_ANNOTATIONS = ImmutableSet.of(Observes.class, ObservesAsync.class); @@ -158,7 +144,14 @@ protected EnhancedAnnotatedTypeImpl(SlimAnnotatedType annotatedType, this.superclass = classTransformer.getEnhancedAnnotatedType(superclass, slim.getIdentifier().getBdaId()); } } else { - this.superclass = classTransformer.getEnhancedAnnotatedType(Object.class, AnnotatedTypeIdentifier.NULL_BDA_ID); + EnhancedAnnotatedType superclassAt; + Class superclass = annotatedType.getJavaClass().getSuperclass(); + if (superclass == null) { + superclassAt = classTransformer.getEnhancedAnnotatedType(Object.class, AnnotatedTypeIdentifier.NULL_BDA_ID); + } else { + superclassAt = classTransformer.getEnhancedAnnotatedType(superclass, slim.getIdentifier().getBdaId()); + } + this.superclass = superclassAt; } // Assign class field information @@ -189,7 +182,7 @@ protected EnhancedAnnotatedTypeImpl(SlimAnnotatedType annotatedType, } this.declaredFields = new HashSet>(declaredFieldsTemp); } else { - Multimap, EnhancedAnnotatedField> annotatedFields = new ListMultimap, EnhancedAnnotatedField>(); + Multimap, EnhancedAnnotatedField> annotatedFields = new ListMultimap<>(); fieldsTemp = new HashSet>(); for (AnnotatedField annotatedField : annotatedType.getFields()) { EnhancedAnnotatedField weldField = EnhancedAnnotatedFieldImpl.of(annotatedField, this, @@ -345,10 +338,8 @@ protected EnhancedAnnotatedTypeImpl(SlimAnnotatedType annotatedType, Set> effectiveMethods) { Multimap, EnhancedAnnotatedMethod> result = SetMultimap.newSetMultimap(); for (EnhancedAnnotatedMethod method : effectiveMethods) { - for (Class annotation : MAPPED_METHOD_ANNOTATIONS) { - if (method.isAnnotationPresent(annotation)) { - result.put(annotation, method); - } + for (Annotation ann : method.getAnnotations()) { + result.put(ann.annotationType(), method); } } return Multimaps.unmodifiableMultimap(result); @@ -446,7 +437,7 @@ public EnhancedAnnotatedConstructor getDeclaredEnhancedConstructor(Constructo public Collection> getEnhancedFields(Class annotationType) { if (annotatedFields == null) { // Build collection from class hierarchy - ArrayList> aggregatedFields = new ArrayList>( + ArrayList> aggregatedFields = new ArrayList<>( this.declaredAnnotatedFields.get(annotationType)); if ((superclass != null) && (superclass.getJavaClass() != Object.class)) { aggregatedFields.addAll(superclass.getEnhancedFields(annotationType)); @@ -490,8 +481,6 @@ public boolean isSerializable() { /** * Gets the abstracted methods that have a certain annotation type present - *

- * If the annotated methods map is null, initialize it first * * @param annotationType The annotation type to match * @return A set of matching method abstractions. Returns an empty set if no diff --git a/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/Foo.java b/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/Foo.java new file mode 100644 index 00000000000..7b320b7f46d --- /dev/null +++ b/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/Foo.java @@ -0,0 +1,14 @@ +package org.jboss.weld.tests.injectionPoint.resource.extension; + +import jakarta.annotation.Resource; +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class Foo { + @Resource(name = "org.jboss.weld.tests.reproducer.Foo/world") + private String value; + + public String value() { + return "hello " + value; + } +} diff --git a/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/FooSpecialized.java b/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/FooSpecialized.java new file mode 100644 index 00000000000..3fd0ecab6e2 --- /dev/null +++ b/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/FooSpecialized.java @@ -0,0 +1,9 @@ +package org.jboss.weld.tests.injectionPoint.resource.extension; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Specializes; + +@ApplicationScoped +@Specializes +public class FooSpecialized extends Foo { +} diff --git a/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/FooSpecializedNoBeanDef.java b/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/FooSpecializedNoBeanDef.java new file mode 100644 index 00000000000..8d74c464552 --- /dev/null +++ b/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/FooSpecializedNoBeanDef.java @@ -0,0 +1,8 @@ +package org.jboss.weld.tests.injectionPoint.resource.extension; + +import jakarta.enterprise.inject.Specializes; + +// no bean defining annotation - this bean is not picked up via discovery but is instead registered via extension +@Specializes +public class FooSpecializedNoBeanDef extends Foo { +} diff --git a/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/MyExtension.java b/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/MyExtension.java new file mode 100644 index 00000000000..1a4ccc3f880 --- /dev/null +++ b/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/MyExtension.java @@ -0,0 +1,14 @@ +package org.jboss.weld.tests.injectionPoint.resource.extension; + +import jakarta.enterprise.event.Observes; +import jakarta.enterprise.inject.spi.AfterTypeDiscovery; +import jakarta.enterprise.inject.spi.BeanManager; +import jakarta.enterprise.inject.spi.Extension; + +public class MyExtension implements Extension { + + void afterTypeDiscovery(@Observes AfterTypeDiscovery event, BeanManager bm) { + event.addAnnotatedType(bm.createAnnotatedType(FooSpecializedNoBeanDef.class), + FooSpecializedNoBeanDef.class.getName() + "_synth"); + } +} diff --git a/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/SpecializationDiscoveryTest.java b/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/SpecializationDiscoveryTest.java new file mode 100644 index 00000000000..0cf18887816 --- /dev/null +++ b/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/SpecializationDiscoveryTest.java @@ -0,0 +1,46 @@ +package org.jboss.weld.tests.injectionPoint.resource.extension; + +import static org.junit.Assert.assertEquals; + +import jakarta.inject.Inject; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.weld.test.util.Utils; +import org.jboss.weld.tests.category.Integration; +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +/** + * Test inheritance of {@code @Resource} field when adding a specialized bean through discovery versus through extension + * See https://issues.redhat.com/browse/WELD-2798 + */ +@Category(Integration.class) +@RunWith(Arquillian.class) +public class SpecializationDiscoveryTest { + + @Deployment + public static Archive deploy() { + return ShrinkWrap + .create(WebArchive.class, + Utils.getDeploymentNameAsHash(SpecializationDiscoveryTest.class, Utils.ARCHIVE_TYPE.WAR)) + .addClasses(Foo.class, FooSpecialized.class, SpecializationDiscoveryTest.class) + .addAsWebInfResource(SpecializationDiscoveryTest.class.getPackage(), "web.xml", "web.xml"); + } + + @Inject + Foo foo; + + @Test + public void test() { + // foo is an instance of the specialized bean + Assert.assertTrue(foo instanceof FooSpecialized); + // resource has been injected + assertEquals("hello world", foo.value()); + } +} diff --git a/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/SpecializationExtensionTest.java b/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/SpecializationExtensionTest.java new file mode 100644 index 00000000000..9aa5b891390 --- /dev/null +++ b/tests-arquillian/src/test/java/org/jboss/weld/tests/injectionPoint/resource/extension/SpecializationExtensionTest.java @@ -0,0 +1,53 @@ +package org.jboss.weld.tests.injectionPoint.resource.extension; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import jakarta.enterprise.inject.spi.Extension; +import jakarta.inject.Inject; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.weld.test.util.Utils; +import org.jboss.weld.tests.category.Integration; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +/** + * Test inheritance of {@code @Resource} field when adding a specialized bean through discovery versus through extension + * See https://issues.redhat.com/browse/WELD-2798 + */ +@Category(Integration.class) +@RunWith(Arquillian.class) +public class SpecializationExtensionTest { + + @Deployment + public static Archive deploy() { + return ShrinkWrap + .create(WebArchive.class, + Utils.getDeploymentNameAsHash(SpecializationExtensionTest.class, Utils.ARCHIVE_TYPE.WAR)) + .addClasses(Foo.class, FooSpecializedNoBeanDef.class, MyExtension.class, + SpecializationExtensionTest.class) + .addAsServiceProvider(Extension.class, MyExtension.class) + .addAsWebInfResource(SpecializationExtensionTest.class.getPackage(), "web.xml", "web.xml") + // archive has an extension, it also needs beans.xml to be considered bean archive + .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); + + } + + @Inject + Foo foo; + + @Test + public void test() { + // foo is an instance of the specialized bean + assertTrue(foo instanceof FooSpecializedNoBeanDef); + // resource has been injected + assertEquals("hello world", foo.value()); + } +} diff --git a/tests-arquillian/src/test/resources/org/jboss/weld/tests/injectionPoint/resource/extension/web.xml b/tests-arquillian/src/test/resources/org/jboss/weld/tests/injectionPoint/resource/extension/web.xml new file mode 100644 index 00000000000..b90c178acfa --- /dev/null +++ b/tests-arquillian/src/test/resources/org/jboss/weld/tests/injectionPoint/resource/extension/web.xml @@ -0,0 +1,15 @@ + + + + Resource Injection Tests + + + org.jboss.weld.tests.reproducer.Foo/world + java.lang.String + world + + + \ No newline at end of file