Skip to content

Commit

Permalink
WELD-2798 Correct injection into injected @resource fields; add autom…
Browse files Browse the repository at this point in the history
…ated test
  • Loading branch information
manovotn committed Oct 2, 2024
1 parent 895bcd6 commit d382291
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -71,17 +68,6 @@
*/
public class EnhancedAnnotatedTypeImpl<T> extends AbstractEnhancedAnnotated<T, Class<T>> implements EnhancedAnnotatedType<T> {

private static final Set<Class<? extends Annotation>> MAPPED_METHOD_ANNOTATIONS;

static {
Set<Class<? extends Annotation>> annotations = new HashSet<Class<? extends Annotation>>();
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<Class<? extends Annotation>> MAPPED_METHOD_PARAMETER_ANNOTATIONS = ImmutableSet.of(Observes.class,
ObservesAsync.class);
Expand Down Expand Up @@ -158,7 +144,14 @@ protected EnhancedAnnotatedTypeImpl(SlimAnnotatedType<T> annotatedType,
this.superclass = classTransformer.getEnhancedAnnotatedType(superclass, slim.getIdentifier().getBdaId());
}
} else {
this.superclass = classTransformer.getEnhancedAnnotatedType(Object.class, AnnotatedTypeIdentifier.NULL_BDA_ID);
EnhancedAnnotatedType<? super T> superclassAt;
Class<? super T> 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
Expand Down Expand Up @@ -189,7 +182,7 @@ protected EnhancedAnnotatedTypeImpl(SlimAnnotatedType<T> annotatedType,
}
this.declaredFields = new HashSet<EnhancedAnnotatedField<?, ? super T>>(declaredFieldsTemp);
} else {
Multimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ?>> annotatedFields = new ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ?>>();
Multimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ?>> annotatedFields = new ListMultimap<>();
fieldsTemp = new HashSet<EnhancedAnnotatedField<?, ? super T>>();
for (AnnotatedField<? super T> annotatedField : annotatedType.getFields()) {
EnhancedAnnotatedField<?, ? super T> weldField = EnhancedAnnotatedFieldImpl.of(annotatedField, this,
Expand Down Expand Up @@ -345,10 +338,8 @@ protected EnhancedAnnotatedTypeImpl(SlimAnnotatedType<T> annotatedType,
Set<EnhancedAnnotatedMethod<?, ? super T>> effectiveMethods) {
Multimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> result = SetMultimap.newSetMultimap();
for (EnhancedAnnotatedMethod<?, ? super T> method : effectiveMethods) {
for (Class<? extends Annotation> 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);
Expand Down Expand Up @@ -446,7 +437,7 @@ public EnhancedAnnotatedConstructor<T> getDeclaredEnhancedConstructor(Constructo
public Collection<EnhancedAnnotatedField<?, ?>> getEnhancedFields(Class<? extends Annotation> annotationType) {
if (annotatedFields == null) {
// Build collection from class hierarchy
ArrayList<EnhancedAnnotatedField<?, ?>> aggregatedFields = new ArrayList<EnhancedAnnotatedField<?, ?>>(
ArrayList<EnhancedAnnotatedField<?, ?>> aggregatedFields = new ArrayList<>(
this.declaredAnnotatedFields.get(annotationType));
if ((superclass != null) && (superclass.getJavaClass() != Object.class)) {
aggregatedFields.addAll(superclass.getEnhancedFields(annotationType));
Expand Down Expand Up @@ -490,8 +481,6 @@ public boolean isSerializable() {

/**
* Gets the abstracted methods that have a certain annotation type present
* <p/>
* 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
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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 {
}
Original file line number Diff line number Diff line change
@@ -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 {
}
Original file line number Diff line number Diff line change
@@ -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");
}
}
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

<display-name>Resource Injection Tests</display-name>

<env-entry>
<env-entry-name>org.jboss.weld.tests.reproducer.Foo/world</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>world</env-entry-value>
</env-entry>

</web-app>

0 comments on commit d382291

Please sign in to comment.