diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Types.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Types.java index 5066d07f874d2..878c6404afb76 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Types.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Types.java @@ -21,6 +21,7 @@ import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationTarget; import org.jboss.jandex.AnnotationValue; +import org.jboss.jandex.ArrayType; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.FieldInfo; @@ -186,13 +187,26 @@ private static void getTypeHandle(AssignableResultHandle variable, BytecodeCreat getParameterizedType(variable, creator, tccl, type.asParameterizedType(), cache, typeVariables); } else if (Kind.ARRAY.equals(type.kind())) { - Type componentType = type.asArrayType().component(); - // E.g. String[] -> new GenericArrayTypeImpl(String.class) - AssignableResultHandle componentTypeHandle = creator.createVariable(Object.class); - getTypeHandle(componentTypeHandle, creator, componentType, tccl, cache, typeVariables); - ResultHandle arrayHandle = creator.newInstance( - MethodDescriptor.ofConstructor(GenericArrayTypeImpl.class, java.lang.reflect.Type.class), - componentTypeHandle); + ArrayType array = type.asArrayType(); + Type elementType = array.component(); + while (elementType.kind() == Kind.ARRAY) { + elementType = elementType.asArrayType().component(); + } + + ResultHandle arrayHandle; + if (elementType.kind() == Kind.PRIMITIVE || elementType.kind() == Kind.CLASS) { + // can produce a java.lang.Class representation of the array type + // E.g. String[] -> String[].class + arrayHandle = doLoadClass(creator, array.name().toString(), tccl); + } else { + // E.g. List[] -> new GenericArrayTypeImpl(new ParameterizedTypeImpl(List.class, String.class)) + Type componentType = type.asArrayType().component(); + AssignableResultHandle componentTypeHandle = creator.createVariable(Object.class); + getTypeHandle(componentTypeHandle, creator, componentType, tccl, cache, typeVariables); + arrayHandle = creator.newInstance( + MethodDescriptor.ofConstructor(GenericArrayTypeImpl.class, java.lang.reflect.Type.class), + componentTypeHandle); + } if (cache != null) { cache.put(type, arrayHandle, creator); } diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/bean/types/ArrayBeanTypesTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/bean/types/ArrayBeanTypesTest.java new file mode 100644 index 0000000000000..90d3ae1b2b2fb --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/bean/types/ArrayBeanTypesTest.java @@ -0,0 +1,72 @@ +package io.quarkus.arc.test.bean.types; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.lang.reflect.Type; +import java.util.List; +import java.util.Set; + +import javax.enterprise.context.Dependent; +import javax.enterprise.inject.Produces; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.util.TypeLiteral; +import javax.inject.Named; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.arc.Arc; +import io.quarkus.arc.InjectableBean; +import io.quarkus.arc.test.ArcTestContainer; + +public class ArrayBeanTypesTest { + @RegisterExtension + ArcTestContainer container = new ArcTestContainer(Producer.class); + + @Test + public void test() { + InjectableBean intArray = Arc.container().instance("intArray").getBean(); + assertBeanTypes(intArray, Object.class, int[][].class); + + InjectableBean stringArray = Arc.container().instance("stringArray").getBean(); + assertBeanTypes(stringArray, Object.class, String[].class); + + InjectableBean listArray = Arc.container().instance("listArray").getBean(); + assertBeanTypes(listArray, Object.class, new TypeLiteral[]>() { + }.getType()); + } + + private void assertBeanTypes(Bean bean, Type... expectedTypes) { + Set types = bean.getTypes(); + + assertEquals(expectedTypes.length, types.size()); + for (Type expectedType : expectedTypes) { + assertTrue(types.contains(expectedType)); + } + } + + @Dependent + static class Producer { + @Produces + @Dependent + @Named("intArray") + int[][] intArray() { + return new int[0][0]; + } + + @Produces + @Dependent + @Named("stringArray") + String[] stringArray() { + return new String[0]; + } + + @Produces + @Dependent + @Named("listArray") + List[] listArray() { + return (List[]) new List[0]; + } + } +}