From c1067bde8cd836461f7b800000f281c87e4cdeeb Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Tue, 14 Nov 2023 17:12:30 +0100 Subject: [PATCH] ArC: fix some corner cases in Build Compatible Extensions - support observing interceptors in `@Registration` - fix reporting priority of beans that are not alternatives (not very useful in standard CDI, but in ArC, we go beyond the standard) - fix NPE in `ClassInfo.methods()` (and `fields()`) for `java.lang.Object` --- .../quarkus/arc/processor/BeanDeployment.java | 2 +- .../processor/bcextensions/BeanInfoImpl.java | 2 +- .../processor/bcextensions/ClassInfoImpl.java | 2 +- .../ExtensionPhaseRegistration.java | 13 +++++-- .../bcextensions/ExtensionsEntryPoint.java | 5 ++- .../cdi/bcextensions/RegistrationTest.java | 37 ++++++++++++++++++- 6 files changed, 52 insertions(+), 9 deletions(-) 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 f64a96a1c42f5a..9e68073ea01334 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 @@ -283,7 +283,7 @@ BeanRegistrar.RegistrationContext registerBeans(List beanRegistra buildContext.putInternal(Key.INJECTION_POINTS, Collections.unmodifiableList(this.injectionPoints)); if (buildCompatibleExtensions != null) { - buildCompatibleExtensions.runRegistration(beanArchiveComputingIndex, beans, observers); + buildCompatibleExtensions.runRegistration(beanArchiveComputingIndex, beans, interceptors, observers); } return registerSyntheticBeans(beanRegistrars, buildContext); diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/BeanInfoImpl.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/BeanInfoImpl.java index f4558bef257b9c..7be224753d5cca 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/BeanInfoImpl.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/BeanInfoImpl.java @@ -105,7 +105,7 @@ public boolean isAlternative() { @Override public Integer priority() { - return arcBeanInfo.getAlternativePriority(); + return arcBeanInfo.getPriority(); } @Override diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/ClassInfoImpl.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/ClassInfoImpl.java index 4175392a021ce0..d39cdd033e8e6e 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/ClassInfoImpl.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/ClassInfoImpl.java @@ -166,7 +166,7 @@ private List allSupertypes() { alreadySeen.add(clazz.name()); DotName superClassName = clazz.superName(); - if (!DotNames.OBJECT.equals(superClassName)) { + if (superClassName != null && !DotNames.OBJECT.equals(superClassName)) { org.jboss.jandex.ClassInfo superClass = jandexIndex.getClassByName(superClassName); workQueue.add(superClass); } diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/ExtensionPhaseRegistration.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/ExtensionPhaseRegistration.java index 0e0b3513c8a725..a8758561b3fae0 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/ExtensionPhaseRegistration.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/ExtensionPhaseRegistration.java @@ -6,23 +6,30 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; import jakarta.enterprise.inject.build.compatible.spi.BeanInfo; import jakarta.enterprise.inject.build.compatible.spi.ObserverInfo; import jakarta.enterprise.inject.spi.DefinitionException; +import org.jboss.jandex.IndexView; + +import io.quarkus.arc.processor.InterceptorInfo; + class ExtensionPhaseRegistration extends ExtensionPhaseBase { private final AllAnnotationOverlays annotationOverlays; private final Collection allBeans; + private final Collection allInterceptors; private final Collection allObservers; private final io.quarkus.arc.processor.AssignabilityCheck assignability; - ExtensionPhaseRegistration(ExtensionInvoker invoker, org.jboss.jandex.IndexView beanArchiveIndex, SharedErrors errors, + ExtensionPhaseRegistration(ExtensionInvoker invoker, IndexView beanArchiveIndex, SharedErrors errors, AllAnnotationOverlays annotationOverlays, Collection allBeans, - Collection allObservers) { + Collection allInterceptors, Collection allObservers) { super(ExtensionPhase.REGISTRATION, invoker, beanArchiveIndex, errors); this.annotationOverlays = annotationOverlays; this.allBeans = allBeans; + this.allInterceptors = allInterceptors; this.allObservers = allObservers; this.assignability = new io.quarkus.arc.processor.AssignabilityCheck(beanArchiveIndex, null); } @@ -84,7 +91,7 @@ private Set expectedTypes(org.jboss.jandex.MethodInfo jan private List matchingBeans(org.jboss.jandex.MethodInfo jandexMethod, boolean onlyInterceptors) { Set expectedTypes = expectedTypes(jandexMethod); - return allBeans.stream() + return Stream.concat(allBeans.stream(), allInterceptors.stream()) .filter(bean -> { if (onlyInterceptors && !bean.isInterceptor()) { return false; diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/ExtensionsEntryPoint.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/ExtensionsEntryPoint.java index cf490e5604ff8d..8f5a390c482145 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/ExtensionsEntryPoint.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/ExtensionsEntryPoint.java @@ -272,6 +272,7 @@ public void runEnhancement(org.jboss.jandex.IndexView beanArchiveIndex, BeanProc */ public void runRegistration(org.jboss.jandex.IndexView beanArchiveIndex, Collection allBeans, + Collection allInterceptors, Collection allObservers) { if (invoker.isEmpty()) { return; @@ -281,7 +282,7 @@ public void runRegistration(org.jboss.jandex.IndexView beanArchiveIndex, try { new ExtensionPhaseRegistration(invoker, beanArchiveIndex, errors, annotationOverlays, - allBeans, allObservers).run(); + allBeans, allInterceptors, allObservers).run(); } finally { BuildServicesImpl.reset(); } @@ -563,7 +564,7 @@ public void runRegistrationAgain(org.jboss.jandex.IndexView beanArchiveIndex, try { new ExtensionPhaseRegistration(invoker, beanArchiveIndex, errors, annotationOverlays, - syntheticBeans, syntheticObservers).run(); + syntheticBeans, Collections.emptyList(), syntheticObservers).run(); } finally { BuildServicesImpl.reset(); } diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/cdi/bcextensions/RegistrationTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/cdi/bcextensions/RegistrationTest.java index 699c54c725d161..f5d05c9c4dc9fb 100644 --- a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/cdi/bcextensions/RegistrationTest.java +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/cdi/bcextensions/RegistrationTest.java @@ -2,21 +2,29 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.util.concurrent.atomic.AtomicInteger; +import jakarta.annotation.Priority; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Initialized; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.build.compatible.spi.BeanInfo; import jakarta.enterprise.inject.build.compatible.spi.BuildCompatibleExtension; +import jakarta.enterprise.inject.build.compatible.spi.Messages; import jakarta.enterprise.inject.build.compatible.spi.ObserverInfo; import jakarta.enterprise.inject.build.compatible.spi.Registration; import jakarta.enterprise.inject.build.compatible.spi.Types; import jakarta.inject.Qualifier; import jakarta.inject.Singleton; +import jakarta.interceptor.AroundInvoke; +import jakarta.interceptor.Interceptor; +import jakarta.interceptor.InterceptorBinding; +import jakarta.interceptor.InvocationContext; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -26,7 +34,8 @@ public class RegistrationTest { @RegisterExtension public ArcTestContainer container = ArcTestContainer.builder() - .beanClasses(MyQualifier.class, MyService.class, MyFooService.class, MyBarService.class, MyBarServiceProducer.class) + .beanClasses(MyQualifier.class, MyInterceptorBinding.class, MyInterceptor.class, MyService.class, + MyFooService.class, MyBarService.class, MyBarServiceProducer.class) .buildCompatibleExtensions(new MyExtension()) .build(); @@ -35,12 +44,14 @@ public void test() { assertEquals(2, MyExtension.beanCounter.get()); assertEquals(1, MyExtension.beanMyQualifierCounter.get()); assertEquals(1, MyExtension.observerQualifierCounter.get()); + assertEquals(1, MyExtension.interceptorCounter.get()); } public static class MyExtension implements BuildCompatibleExtension { static final AtomicInteger beanCounter = new AtomicInteger(); static final AtomicInteger beanMyQualifierCounter = new AtomicInteger(); static final AtomicInteger observerQualifierCounter = new AtomicInteger(); + static final AtomicInteger interceptorCounter = new AtomicInteger(); @Registration(types = MyService.class) public void beans(BeanInfo bean) { @@ -57,6 +68,14 @@ public void observers(ObserverInfo observer, Types types) { observerQualifierCounter.addAndGet(observer.qualifiers().size()); } } + + @Registration(types = MyInterceptor.class) + public void interceptors(BeanInfo interceptor, Messages msg) { + if (!interceptor.isInterceptor()) { + msg.error("Interceptor expected", interceptor); + } + interceptorCounter.incrementAndGet(); + } } // --- @@ -66,6 +85,22 @@ public void observers(ObserverInfo observer, Types types) { public @interface MyQualifier { } + @Target({ ElementType.TYPE, ElementType.METHOD }) + @Retention(RetentionPolicy.RUNTIME) + @InterceptorBinding + public @interface MyInterceptorBinding { + } + + @MyInterceptorBinding + @Interceptor + @Priority(1) + public static class MyInterceptor { + @AroundInvoke + public Object intercept(InvocationContext ctx) throws Exception { + return ctx.proceed(); + } + } + public interface MyService { String hello(); }