diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java index 1deca533a82e6..4f9ccde761def 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java @@ -291,28 +291,28 @@ void init(Consumer<BytecodeTransformer> bytecodeTransformerConsumer, private void initBeanByTypeMap() { Map<DotName, List<BeanInfo>> map = new HashMap<>(); for (BeanInfo bean : beans) { - for (Type beanType : bean.types) { - if (DotNames.OBJECT.equals(beanType.name())) { + bean.types.stream().map(Type::name).distinct().forEach(rawTypeName -> { + if (DotNames.OBJECT.equals(rawTypeName)) { // Every bean has java.lang.Object - no need to cache results here - continue; + return; } - List<BeanInfo> beans = map.get(beanType.name()); + List<BeanInfo> beans = map.get(rawTypeName); if (beans == null) { // Very often, there will be exactly one bean for a given type - map.put(beanType.name(), List.of(bean)); + map.put(rawTypeName, List.of(bean)); } else { if (beans.size() == 1) { - map.put(beanType.name(), List.of(beans.get(0), bean)); + map.put(rawTypeName, List.of(beans.get(0), bean)); } else { BeanInfo[] array = new BeanInfo[beans.size() + 1]; for (int i = 0; i < beans.size(); i++) { array[i] = beans.get(i); } array[beans.size()] = bean; - map.put(beanType.name(), List.of(array)); + map.put(rawTypeName, List.of(array)); } } - } + }); } this.beansByType = map; } diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/buildextension/beans/BeanRegistrarTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/buildextension/beans/BeanRegistrarTest.java index dec25178504ed..06a86fe616e9e 100644 --- a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/buildextension/beans/BeanRegistrarTest.java +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/buildextension/beans/BeanRegistrarTest.java @@ -20,15 +20,19 @@ import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.Target; +import java.util.List; import java.util.Map; import java.util.Optional; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.util.AnnotationLiteral; +import javax.inject.Inject; import javax.inject.Qualifier; import javax.inject.Singleton; import org.jboss.jandex.DotName; +import org.jboss.jandex.ParameterizedType; import org.jboss.jandex.Type; +import org.jboss.jandex.Type.Kind; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -40,8 +44,9 @@ public class BeanRegistrarTest { @RegisterExtension public ArcTestContainer container = ArcTestContainer.builder() - .beanClasses(UselessBean.class, MyQualifier.class, NextQualifier.class) + .beanClasses(UselessBean.class, MyQualifier.class, NextQualifier.class, ListConsumer.class) .removeUnusedBeans(true) + .addRemovalExclusion(b -> b.hasType(DotName.createSimple(ListConsumer.class.getName()))) .beanRegistrars(new TestRegistrar()).build(); @AfterAll @@ -74,6 +79,18 @@ public void testSyntheticBean() { assertEquals(Integer.valueOf(152), Arc.container().instance(Integer.class).get()); assertEquals("Hello Frantisek!", Arc.container().instance(String.class).get()); assertEquals("Hello Roman!", Arc.container().instance(String.class, new NextQualifierLiteral()).get()); + @SuppressWarnings({ "resource" }) + List<String> list = Arc.container().instance(ListConsumer.class).get().list; + assertEquals(1, list.size()); + assertEquals("foo", list.get(0)); + } + + @Singleton + static class ListConsumer { + + @Inject + List<String> list; + } static class TestRegistrar implements BeanRegistrar { @@ -102,13 +119,28 @@ public void register(RegistrationContext context) { integerConfigurator.scope(Singleton.class); integerConfigurator.done(); - context.configure(String.class).unremovable().types(String.class).param("name", "Frantisek") - .creator(StringCreator.class).done(); + context.configure(String.class) + .unremovable() + .types(String.class) + .param("name", "Frantisek") + .creator(StringCreator.class) + .done(); context.configure(String.class).types(String.class).param("name", "Roman") - .creator(StringCreator.class).addQualifier().annotation(NextQualifier.class).addValue("name", "Roman") - .addValue("age", 42) - .addValue("classes", new Class[] { String.class }).done().unremovable().done(); + .creator(StringCreator.class) + .addQualifier().annotation(NextQualifier.class).addValue("name", "Roman").addValue("age", 42) + .addValue("classes", new Class[] { String.class }).done() + .unremovable() + .done(); + + context.configure(List.class) + // List, List<String> + .addType(Type.create(DotName.createSimple(List.class.getName()), Kind.CLASS)) + .addType(ParameterizedType.create(DotName.createSimple(List.class.getName()), + new Type[] { Type.create(DotName.createSimple(String.class.getName()), Kind.CLASS) }, null)) + .creator(ListCreator.class) + .unremovable() + .done(); uselessBean = context.beans() .assignableTo( @@ -129,6 +161,15 @@ public String create(CreationalContext<String> creationalContext, Map<String, Ob } + public static class ListCreator implements BeanCreator<List<String>> { + + @Override + public List<String> create(CreationalContext<List<String>> creationalContext, Map<String, Object> params) { + return List.of("foo"); + } + + } + public static class SimpleDestroyer implements BeanDestroyer<Integer> { @Override