diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BuiltinBean.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BuiltinBean.java index 571afe47a3c28..4450caacfd4ef 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BuiltinBean.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BuiltinBean.java @@ -375,7 +375,7 @@ private static void generateListBytecode(GeneratorContext ctx) { InjectionPointInfo injectionPoint = ctx.injectionPoint; if (injectionPoint.isField()) { ctx.reflectionRegistration.registerField(injectionPoint.getAnnotationTarget().asField()); - } else { + } else if (injectionPoint.isParam()) { ctx.reflectionRegistration.registerMethod(injectionPoint.getAnnotationTarget().asMethodParameter().method()); } @@ -475,6 +475,13 @@ private static void validateList(InjectionTargetInfo injectionTarget, InjectionP // Note that at this point we can be sure that the required type is List<> Type typeParam = injectionPoint.getType().asParameterizedType().arguments().get(0); if (typeParam.kind() == Type.Kind.WILDCARD_TYPE) { + if (injectionPoint.isSynthetic()) { + errors.accept( + new DefinitionException( + "Wildcard is not a legal type argument for a synthetic @All List injection point used in: " + + injectionTarget.toString())); + return; + } ClassInfo declaringClass; if (injectionPoint.isField()) { declaringClass = injectionPoint.getAnnotationTarget().asField().declaringClass(); diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/buildextension/beans/SyntheticInjectionPointListAllInvalidTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/buildextension/beans/SyntheticInjectionPointListAllInvalidTest.java new file mode 100644 index 0000000000000..46a1d91c6b095 --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/buildextension/beans/SyntheticInjectionPointListAllInvalidTest.java @@ -0,0 +1,70 @@ +package io.quarkus.arc.test.buildextension.beans; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; + +import jakarta.enterprise.util.TypeLiteral; + +import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.ClassType; +import org.jboss.jandex.DotName; +import org.jboss.jandex.ParameterizedType; +import org.jboss.jandex.WildcardType; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.arc.All; +import io.quarkus.arc.BeanCreator; +import io.quarkus.arc.SyntheticCreationalContext; +import io.quarkus.arc.processor.BeanRegistrar; +import io.quarkus.arc.test.ArcTestContainer; + +public class SyntheticInjectionPointListAllInvalidTest { + + @RegisterExtension + public ArcTestContainer container = ArcTestContainer.builder() + .beanRegistrars(new TestRegistrar()) + .shouldFail() + .build(); + + @Test + public void testListAllInjection() { + assertNotNull(container.getFailure()); + assertTrue(container.getFailure().getMessage().contains( + "Wildcard is not a legal type argument for a synthetic @All List injection point")); + } + + static class SyntheticBean { + + public SyntheticBean(List list) { + } + } + + static class TestRegistrar implements BeanRegistrar { + + @Override + public void register(RegistrationContext context) { + context.configure(SyntheticBean.class) + .addType(ClassType.create(DotName.createSimple(SyntheticBean.class))) + .creator(SynthBeanCreator.class) + // add injection point for @All List - wildcard is NOT a legal bean type + .addInjectionPoint(ParameterizedType.create(List.class, WildcardType.UNBOUNDED), + AnnotationInstance.builder(All.class).build()) + .unremovable() + .done(); + } + + } + + public static class SynthBeanCreator implements BeanCreator { + + @Override + public SyntheticBean create(SyntheticCreationalContext context) { + return new SyntheticBean(context.getInjectedReference(new TypeLiteral>() { + }, All.Literal.INSTANCE)); + } + + } +} diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/buildextension/beans/SyntheticInjectionPointListAllTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/buildextension/beans/SyntheticInjectionPointListAllTest.java new file mode 100644 index 0000000000000..0b059a6f83600 --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/buildextension/beans/SyntheticInjectionPointListAllTest.java @@ -0,0 +1,88 @@ +package io.quarkus.arc.test.buildextension.beans; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.util.List; + +import jakarta.enterprise.util.TypeLiteral; +import jakarta.inject.Singleton; + +import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.ClassType; +import org.jboss.jandex.DotName; +import org.jboss.jandex.ParameterizedType; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.arc.All; +import io.quarkus.arc.Arc; +import io.quarkus.arc.BeanCreator; +import io.quarkus.arc.SyntheticCreationalContext; +import io.quarkus.arc.processor.BeanRegistrar; +import io.quarkus.arc.test.ArcTestContainer; + +public class SyntheticInjectionPointListAllTest { + + @RegisterExtension + public ArcTestContainer container = ArcTestContainer.builder() + .beanClasses(SomeBean.class) + .beanRegistrars(new TestRegistrar()).build(); + + @Test + public void testListAllInjection() { + SyntheticBean synthBean = Arc.container().instance(SyntheticBean.class).get(); + assertNotNull(synthBean); + List list = synthBean.getList(); + assertNotNull(list); + assertEquals(1, list.size()); + } + + @Singleton + static class SomeBean { + + public String ping() { + return SomeBean.class.getSimpleName(); + } + + } + + static class SyntheticBean { + + private List list; + + public SyntheticBean(List list) { + this.list = list; + } + + public List getList() { + return list; + } + } + + static class TestRegistrar implements BeanRegistrar { + + @Override + public void register(RegistrationContext context) { + context.configure(SyntheticBean.class) + .addType(ClassType.create(DotName.createSimple(SyntheticBean.class))) + .creator(SynthBeanCreator.class) + // add injection point for @All List + .addInjectionPoint(ParameterizedType.create(List.class, ClassType.create(SomeBean.class)), + AnnotationInstance.builder(All.class).build()) + .unremovable() + .done(); + } + + } + + public static class SynthBeanCreator implements BeanCreator { + + @Override + public SyntheticBean create(SyntheticCreationalContext context) { + return new SyntheticBean(context.getInjectedReference(new TypeLiteral>() { + }, All.Literal.INSTANCE)); + } + + } +}