Skip to content

Commit 37e8e28

Browse files
committed
ArC: add validation of synthetic bean types
So far, bean types of synthetic beans were not validated, so it was possible to create synthetic beans with illegal bean types. This commit fixes that. If a synthetic bean has an illegal type, definition error occurs.
1 parent 5b58933 commit 37e8e28

File tree

6 files changed

+257
-11
lines changed

6 files changed

+257
-11
lines changed

independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanConfigurator.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,13 @@ public void done() {
120120
builder.injections(Collections.singletonList(Injection.forSyntheticBean(injectionPoints)));
121121
}
122122

123-
beanConsumer.accept(builder.build());
123+
BeanInfo bean = builder.build();
124+
125+
for (Type type : this.types) {
126+
Types.checkLegalBeanType(type, bean);
127+
}
128+
129+
beanConsumer.accept(bean);
124130
}
125131
}
126132

independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Types.java

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ private static void getTypeHandle(AssignableResultHandle variable, BytecodeCreat
243243

244244
} else if (Kind.ARRAY.equals(type.kind())) {
245245
ArrayType array = type.asArrayType();
246-
Type elementType = getArrayElementType(array);
246+
Type elementType = array.elementType();
247247

248248
ResultHandle arrayHandle;
249249
if (elementType.kind() == Kind.PRIMITIVE || elementType.kind() == Kind.CLASS) {
@@ -420,14 +420,6 @@ static Type getProviderType(ClassInfo classInfo) {
420420
}
421421
}
422422

423-
static Type getArrayElementType(ArrayType array) {
424-
Type elementType = array.constituent();
425-
while (elementType.kind() == Kind.ARRAY) {
426-
elementType = elementType.asArrayType().constituent();
427-
}
428-
return elementType;
429-
}
430-
431423
static TypeClosure getProducerMethodTypeClosure(MethodInfo producerMethod, BeanDeployment beanDeployment) {
432424
Set<Type> types;
433425
Set<Type> unrestrictedBeanTypes = new HashSet<>();
@@ -615,12 +607,39 @@ static List<Type> getResolvedParameters(ClassInfo classInfo, Map<String, Type> r
615607
}
616608
}
617609

610+
/**
611+
* Throws {@code DefinitionException} if given {@code type} is not a legal bean type.
612+
* <p>
613+
* This method is currently only used for synthetic beans. Legal bean types are checked
614+
* for producers through other means (see {@link #checkArrayType(ArrayType, AnnotationTarget) checkArrayType()}
615+
* and {@link #containsWildcard(Type, AnnotationTarget, boolean) containsWildcard()}).
616+
*/
617+
static void checkLegalBeanType(Type type, Object beanDescription) {
618+
if (type.kind() == Kind.TYPE_VARIABLE) {
619+
throw new DefinitionException("Type variable is not a legal bean type: " + beanDescription);
620+
} else if (type.kind() == Kind.PARAMETERIZED_TYPE) {
621+
checkWildcard(type, beanDescription);
622+
} else if (type.kind() == Kind.ARRAY) {
623+
checkLegalBeanType(type.asArrayType().elementType(), beanDescription);
624+
}
625+
}
626+
627+
private static void checkWildcard(Type type, Object beanDescription) {
628+
if (type.kind() == Kind.WILDCARD_TYPE) {
629+
throw new DefinitionException("Wildcard type is not a legal bean type: " + beanDescription);
630+
} else if (type.kind() == Kind.PARAMETERIZED_TYPE) {
631+
for (Type typeArgument : type.asParameterizedType().arguments()) {
632+
checkWildcard(typeArgument, beanDescription);
633+
}
634+
}
635+
}
636+
618637
/**
619638
* Throws {@code DefinitionException} if given {@code producerFieldOrMethod},
620639
* whose type is given {@code arrayType}, is invalid due to the rules for arrays.
621640
*/
622641
static void checkArrayType(ArrayType arrayType, AnnotationTarget producerFieldOrMethod) {
623-
Type elementType = getArrayElementType(arrayType);
642+
Type elementType = arrayType.elementType();
624643
if (elementType.kind() == Kind.TYPE_VARIABLE) {
625644
throw new DefinitionException("A type variable array is not a legal bean type: " + producerFieldOrMethod);
626645
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package io.quarkus.arc.test.buildextension.beans;
2+
3+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
4+
import static org.junit.jupiter.api.Assertions.assertNotNull;
5+
import static org.junit.jupiter.api.Assertions.assertTrue;
6+
7+
import jakarta.enterprise.inject.spi.DefinitionException;
8+
9+
import org.jboss.jandex.ArrayType;
10+
import org.jboss.jandex.TypeVariable;
11+
import org.junit.jupiter.api.Test;
12+
import org.junit.jupiter.api.extension.RegisterExtension;
13+
14+
import io.quarkus.arc.BeanCreator;
15+
import io.quarkus.arc.SyntheticCreationalContext;
16+
import io.quarkus.arc.processor.BeanRegistrar;
17+
import io.quarkus.arc.test.ArcTestContainer;
18+
19+
public class SyntheticBeanWithTypeVariableArrayTest {
20+
@RegisterExtension
21+
public ArcTestContainer container = ArcTestContainer.builder()
22+
.beanRegistrars(new MyBeanRegistrar())
23+
.shouldFail()
24+
.build();
25+
26+
@Test
27+
public void trigger() {
28+
Throwable error = container.getFailure();
29+
assertNotNull(error);
30+
assertInstanceOf(DefinitionException.class, error);
31+
assertTrue(error.getMessage().contains("Type variable is not a legal bean type"));
32+
}
33+
34+
static class MyBean {
35+
}
36+
37+
static class MyBeanCreator implements BeanCreator<MyBean> {
38+
@Override
39+
public MyBean create(SyntheticCreationalContext<MyBean> context) {
40+
return new MyBean();
41+
}
42+
}
43+
44+
static class MyBeanRegistrar implements BeanRegistrar {
45+
@Override
46+
public void register(RegistrationContext context) {
47+
context.configure(MyBean.class)
48+
.addType(MyBean.class)
49+
.addType(ArrayType.create(TypeVariable.create("T"), 1))
50+
.creator(MyBeanCreator.class)
51+
.done();
52+
}
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package io.quarkus.arc.test.buildextension.beans;
2+
3+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
4+
import static org.junit.jupiter.api.Assertions.assertNotNull;
5+
import static org.junit.jupiter.api.Assertions.assertTrue;
6+
7+
import jakarta.enterprise.inject.spi.DefinitionException;
8+
9+
import org.jboss.jandex.TypeVariable;
10+
import org.junit.jupiter.api.Test;
11+
import org.junit.jupiter.api.extension.RegisterExtension;
12+
13+
import io.quarkus.arc.BeanCreator;
14+
import io.quarkus.arc.SyntheticCreationalContext;
15+
import io.quarkus.arc.processor.BeanRegistrar;
16+
import io.quarkus.arc.test.ArcTestContainer;
17+
18+
public class SyntheticBeanWithTypeVariableTest {
19+
@RegisterExtension
20+
public ArcTestContainer container = ArcTestContainer.builder()
21+
.beanRegistrars(new MyBeanRegistrar())
22+
.shouldFail()
23+
.build();
24+
25+
@Test
26+
public void trigger() {
27+
Throwable error = container.getFailure();
28+
assertNotNull(error);
29+
assertInstanceOf(DefinitionException.class, error);
30+
assertTrue(error.getMessage().contains("Type variable is not a legal bean type"));
31+
}
32+
33+
static class MyBean {
34+
}
35+
36+
static class MyBeanCreator implements BeanCreator<MyBean> {
37+
@Override
38+
public MyBean create(SyntheticCreationalContext<MyBean> context) {
39+
return new MyBean();
40+
}
41+
}
42+
43+
static class MyBeanRegistrar implements BeanRegistrar {
44+
@Override
45+
public void register(RegistrationContext context) {
46+
context.configure(MyBean.class)
47+
.addType(MyBean.class)
48+
.addType(TypeVariable.create("T"))
49+
.creator(MyBeanCreator.class)
50+
.done();
51+
}
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package io.quarkus.arc.test.buildextension.beans;
2+
3+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
4+
import static org.junit.jupiter.api.Assertions.assertNotNull;
5+
import static org.junit.jupiter.api.Assertions.assertTrue;
6+
7+
import java.util.List;
8+
9+
import jakarta.enterprise.inject.spi.DefinitionException;
10+
11+
import org.jboss.jandex.ArrayType;
12+
import org.jboss.jandex.ParameterizedType;
13+
import org.jboss.jandex.WildcardType;
14+
import org.junit.jupiter.api.Test;
15+
import org.junit.jupiter.api.extension.RegisterExtension;
16+
17+
import io.quarkus.arc.BeanCreator;
18+
import io.quarkus.arc.SyntheticCreationalContext;
19+
import io.quarkus.arc.processor.BeanRegistrar;
20+
import io.quarkus.arc.test.ArcTestContainer;
21+
22+
public class SyntheticBeanWithWildcardParameterizedTypeArrayTest {
23+
@RegisterExtension
24+
public ArcTestContainer container = ArcTestContainer.builder()
25+
.beanRegistrars(new MyBeanRegistrar())
26+
.shouldFail()
27+
.build();
28+
29+
@Test
30+
public void trigger() {
31+
Throwable error = container.getFailure();
32+
assertNotNull(error);
33+
assertInstanceOf(DefinitionException.class, error);
34+
assertTrue(error.getMessage().contains("Wildcard type is not a legal bean type"));
35+
}
36+
37+
static class MyBean {
38+
}
39+
40+
static class MyBeanCreator implements BeanCreator<MyBean> {
41+
@Override
42+
public MyBean create(SyntheticCreationalContext<MyBean> context) {
43+
return new MyBean();
44+
}
45+
}
46+
47+
static class MyBeanRegistrar implements BeanRegistrar {
48+
@Override
49+
public void register(RegistrationContext context) {
50+
context.configure(MyBean.class)
51+
.addType(MyBean.class)
52+
.addType(ArrayType.create(
53+
ParameterizedType.builder(List.class).addArgument(WildcardType.UNBOUNDED).build(), 2))
54+
.creator(MyBeanCreator.class)
55+
.done();
56+
}
57+
}
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package io.quarkus.arc.test.buildextension.beans;
2+
3+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
4+
import static org.junit.jupiter.api.Assertions.assertNotNull;
5+
import static org.junit.jupiter.api.Assertions.assertTrue;
6+
7+
import java.util.List;
8+
9+
import jakarta.enterprise.inject.spi.DefinitionException;
10+
11+
import org.jboss.jandex.ParameterizedType;
12+
import org.jboss.jandex.WildcardType;
13+
import org.junit.jupiter.api.Test;
14+
import org.junit.jupiter.api.extension.RegisterExtension;
15+
16+
import io.quarkus.arc.BeanCreator;
17+
import io.quarkus.arc.SyntheticCreationalContext;
18+
import io.quarkus.arc.processor.BeanRegistrar;
19+
import io.quarkus.arc.test.ArcTestContainer;
20+
21+
public class SyntheticBeanWithWildcardParameterizedTypeTest {
22+
@RegisterExtension
23+
public ArcTestContainer container = ArcTestContainer.builder()
24+
.beanRegistrars(new MyBeanRegistrar())
25+
.shouldFail()
26+
.build();
27+
28+
@Test
29+
public void trigger() {
30+
Throwable error = container.getFailure();
31+
assertNotNull(error);
32+
assertInstanceOf(DefinitionException.class, error);
33+
assertTrue(error.getMessage().contains("Wildcard type is not a legal bean type"));
34+
}
35+
36+
static class MyBean {
37+
}
38+
39+
static class MyBeanCreator implements BeanCreator<MyBean> {
40+
@Override
41+
public MyBean create(SyntheticCreationalContext<MyBean> context) {
42+
return new MyBean();
43+
}
44+
}
45+
46+
static class MyBeanRegistrar implements BeanRegistrar {
47+
@Override
48+
public void register(RegistrationContext context) {
49+
context.configure(MyBean.class)
50+
.addType(MyBean.class)
51+
.addType(ParameterizedType.builder(List.class).addArgument(WildcardType.UNBOUNDED).build())
52+
.creator(MyBeanCreator.class)
53+
.done();
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)