Skip to content

Commit

Permalink
ArC build time optimization fix
Browse files Browse the repository at this point in the history
- BeanDeployment#beansByType - a bean should not be listed multiple
times even if it has multiple types with the same raw name in its set of
bean types
- fix a regression introduced in #20470
- resolves #20566
  • Loading branch information
mkouba committed Oct 7, 2021
1 parent 3271bbd commit 3ef4e5d
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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(
Expand All @@ -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
Expand Down

0 comments on commit 3ef4e5d

Please sign in to comment.