Skip to content

Commit

Permalink
ArC: fix the situation when a framework bean uses an application deco…
Browse files Browse the repository at this point in the history
…rator

ArC-generated classes for framework beans are by default _not_ application
classes. This causes problems in hierarchical classloader environments
(dev/test mode) when there is an application decorator that applies to
the framework bean.

This commit fixes that issue by turning the ArC-generated classes for framework
beans into application classes whenever an application decorator applies. This
makes package access impossible, which is an unfortunate downside.

The problem doesn't exist in a flat classloading environment, such as prod mode.
  • Loading branch information
Ladicek committed Sep 12, 2024
1 parent 74ef7b3 commit ab60073
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,9 @@ Collection<Resource> generateClassBean(BeanInfo bean, ClassInfo beanClass) {
return Collections.emptyList();
}

boolean isApplicationClass = applicationClassPredicate.test(beanClass.name()) || bean.isForceApplicationClass();
boolean isApplicationClass = applicationClassPredicate.test(beanClass.name())
|| bean.isForceApplicationClass()
|| bean.hasBoundDecoratorWhichIsApplicationClass(applicationClassPredicate);
ResourceClassOutput classOutput = new ResourceClassOutput(isApplicationClass,
name -> name.equals(generatedName) ? SpecialType.BEAN : null, generateSources);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.OptionalInt;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import jakarta.enterprise.inject.Typed;
Expand Down Expand Up @@ -514,6 +515,15 @@ public List<DecoratorInfo> getBoundDecorators() {
return bound;
}

boolean hasBoundDecoratorWhichIsApplicationClass(Predicate<DotName> isApplicationClass) {
for (DecoratorInfo decorator : getBoundDecorators()) {
if (isApplicationClass.test(decorator.getImplClazz().name())) {
return true;
}
}
return false;
}

/**
*
* @return the list of around invoke interceptor methods declared in the hierarchy of a bean class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ Collection<Resource> generate(BeanInfo bean, String beanClassName,
return Collections.emptyList();
}

boolean applicationClass = applicationClassPredicate.test(getApplicationClassTestName(bean));
ResourceClassOutput classOutput = new ResourceClassOutput(applicationClass,
boolean isApplicationClass = applicationClassPredicate.test(getApplicationClassTestName(bean))
|| bean.hasBoundDecoratorWhichIsApplicationClass(applicationClassPredicate);
ResourceClassOutput classOutput = new ResourceClassOutput(isApplicationClass,
name -> name.equals(generatedName) ? SpecialType.CLIENT_PROXY : null, generateSources);

// Foo_ClientProxy extends Foo implements ClientProxy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ Collection<Resource> generate(BeanInfo bean, String beanClassName) {
return Collections.emptyList();
}

ResourceClassOutput classOutput = new ResourceClassOutput(applicationClassPredicate.test(bean.getBeanClass()),
boolean isApplicationClass = applicationClassPredicate.test(bean.getBeanClass())
|| bean.hasBoundDecoratorWhichIsApplicationClass(applicationClassPredicate);
ResourceClassOutput classOutput = new ResourceClassOutput(isApplicationClass,
name -> name.equals(generatedName) ? SpecialType.SUBCLASS : null,
generateSources);

Expand Down

0 comments on commit ab60073

Please sign in to comment.