From edbc29c88760c927cf6c59c4e145880369a93bd1 Mon Sep 17 00:00:00 2001
From: Matej Novotny
Date: Wed, 5 Oct 2022 15:30:53 +0200
Subject: [PATCH 1/3] Revisit the non-standard behavior of
ArcContainer#instanceSupplier() Modify RR and Undertow processors to add
@Typed to the resources they discover as beans
---
.../io/quarkus/arc/runtime/BeanContainer.java | 9 ++-
.../deployment/ResteasyReactiveProcessor.java | 73 +++++++++++++++++++
.../test/response/ChunkedResponseTest.java | 19 ++++-
.../deployment/UndertowBuildStep.java | 38 ++++++++++
.../io/quarkus/arc/impl/ArcContainerImpl.java | 15 +---
.../processor/ResteasyReactiveDotNames.java | 2 +
6 files changed, 139 insertions(+), 17 deletions(-)
diff --git a/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/BeanContainer.java b/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/BeanContainer.java
index 737a99bd19da4..df187a9e0c94c 100644
--- a/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/BeanContainer.java
+++ b/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/BeanContainer.java
@@ -20,9 +20,12 @@ default T instance(Class type, Annotation... qualifiers) {
}
/**
- * Note that if there are multiple sub classes of the given type this will return the exact match. This means
- * that this can be used to directly instantiate superclasses of other beans without causing problems. This behavior differs
- * to standard CDI rules where an ambiguous dependency would exist.
+ * Returns an instance factory for given bean type and qualifiers.
+ *
+ * This method follows standard CDI rules meaning that if there are two or more beans, an ambiguous dependency
+ * exception is thrown.
+ * Note that the factory itself is still allowed to return {@code null} if there is no matching bean which allows
+ * for fallback implementations.
*
* @param type
* @param qualifiers
diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java
index e239f253d6bcf..d7ccf1c31926f 100644
--- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java
+++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java
@@ -42,6 +42,8 @@
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Providers;
+import javax.ws.rs.ext.ReaderInterceptor;
+import javax.ws.rs.ext.WriterInterceptor;
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;
@@ -57,6 +59,8 @@
import org.jboss.resteasy.reactive.common.core.Serialisers;
import org.jboss.resteasy.reactive.common.core.SingletonBeanFactory;
import org.jboss.resteasy.reactive.common.model.InjectableBean;
+import org.jboss.resteasy.reactive.common.model.InterceptorContainer;
+import org.jboss.resteasy.reactive.common.model.PreMatchInterceptorContainer;
import org.jboss.resteasy.reactive.common.model.ResourceClass;
import org.jboss.resteasy.reactive.common.model.ResourceDynamicFeature;
import org.jboss.resteasy.reactive.common.model.ResourceFeature;
@@ -718,6 +722,75 @@ private FilterClassIntrospector createFilterClassIntrospector() {
return ab.get();
}
+ // We want to add @Typed to resources and providers so that they can be resolved as CDI bean using purely their
+ // class as a bean type. This removes any ambiguity that potential subclasses may have.
+ @BuildStep
+ public void transformEndpoints(
+ ResourceScanningResultBuildItem resourceScanningResultBuildItem,
+ ResourceInterceptorsBuildItem resourceInterceptorsBuildItem,
+ BuildProducer annotationsTransformer) {
+
+ // all found resources and sub-resources
+ Set allResources = new HashSet<>();
+ allResources.addAll(resourceScanningResultBuildItem.getResult().getScannedResources().keySet());
+ allResources.addAll(resourceScanningResultBuildItem.getResult().getPossibleSubResources().keySet());
+
+ // discovered filters and interceptors
+ Set filtersAndInterceptors = new HashSet<>();
+ InterceptorContainer readerInterceptors = resourceInterceptorsBuildItem.getResourceInterceptors()
+ .getReaderInterceptors();
+ readerInterceptors.getNameResourceInterceptors().forEach(i -> filtersAndInterceptors.add(i.getClassName()));
+ readerInterceptors.getGlobalResourceInterceptors().forEach(i -> filtersAndInterceptors.add(i.getClassName()));
+ InterceptorContainer writerInterceptors = resourceInterceptorsBuildItem.getResourceInterceptors()
+ .getWriterInterceptors();
+ writerInterceptors.getNameResourceInterceptors().forEach(i -> filtersAndInterceptors.add(i.getClassName()));
+ writerInterceptors.getGlobalResourceInterceptors().forEach(i -> filtersAndInterceptors.add(i.getClassName()));
+ PreMatchInterceptorContainer containerRequestFilters = resourceInterceptorsBuildItem
+ .getResourceInterceptors().getContainerRequestFilters();
+ containerRequestFilters.getPreMatchInterceptors().forEach(i -> filtersAndInterceptors.add(i.getClassName()));
+ containerRequestFilters.getNameResourceInterceptors().forEach(i -> filtersAndInterceptors.add(i.getClassName()));
+ containerRequestFilters.getGlobalResourceInterceptors().forEach(i -> filtersAndInterceptors.add(i.getClassName()));
+ InterceptorContainer containerResponseFilters = resourceInterceptorsBuildItem
+ .getResourceInterceptors().getContainerResponseFilters();
+ containerResponseFilters.getGlobalResourceInterceptors().forEach(i -> filtersAndInterceptors.add(i.getClassName()));
+ containerResponseFilters.getNameResourceInterceptors().forEach(i -> filtersAndInterceptors.add(i.getClassName()));
+
+ annotationsTransformer.produce(new io.quarkus.arc.deployment.AnnotationsTransformerBuildItem(
+ new io.quarkus.arc.processor.AnnotationsTransformer() {
+
+ @Override
+ public boolean appliesTo(AnnotationTarget.Kind kind) {
+ return kind == AnnotationTarget.Kind.CLASS;
+ }
+
+ @Override
+ public void transform(TransformationContext context) {
+ ClassInfo clazz = context.getTarget().asClass();
+ // check if the class is one of resources/sub-resources
+ if (allResources.contains(clazz.name())
+ && clazz.declaredAnnotation(ResteasyReactiveDotNames.TYPED) == null) {
+ context.transform().add(createTypedAnnotationInstance(clazz)).done();
+ return;
+ }
+ // check if the class is one of providers, either explicitly declaring the annotation
+ // or discovered as resource interceptor or filter
+ if ((clazz.declaredAnnotation(ResteasyReactiveDotNames.PROVIDER) != null
+ || filtersAndInterceptors.contains(clazz.name().toString()))
+ && clazz.declaredAnnotation(ResteasyReactiveDotNames.TYPED) == null) {
+ // Add @Typed(MyResource.class)
+ context.transform().add(createTypedAnnotationInstance(clazz)).done();
+ }
+ }
+ }));
+ }
+
+ private AnnotationInstance createTypedAnnotationInstance(ClassInfo clazz) {
+ return AnnotationInstance.create(ResteasyReactiveDotNames.TYPED, clazz,
+ new AnnotationValue[] { AnnotationValue.createArrayValue("value",
+ new AnnotationValue[] { AnnotationValue.createClassValue("value",
+ Type.create(clazz.name(), Type.Kind.CLASS)) }) });
+ }
+
private Collection additionalContextTypes(List contextTypeBuildItems) {
if (contextTypeBuildItems.isEmpty()) {
return CONTEXT_TYPES;
diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/response/ChunkedResponseTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/response/ChunkedResponseTest.java
index 4af67db4b5c03..1bd68e6a2d9bb 100644
--- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/response/ChunkedResponseTest.java
+++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/response/ChunkedResponseTest.java
@@ -30,7 +30,7 @@ public class ChunkedResponseTest {
static QuarkusUnitTest runner = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClasses(HelloResource.class)
- .addAsResource(new StringAsset("quarkus.rest.output-buffer-size = 256"),
+ .addAsResource(new StringAsset("quarkus.resteasy-reactive.output-buffer-size = 256"),
"application.properties"));
@Test
@@ -68,7 +68,22 @@ public String helloSmall() {
}
@Provider
- public static final class CustomStringMessageBodyWriter extends ServerStringMessageBodyHandler {
+ public static class CustomStringMessageBodyWriter extends ServerStringMessageBodyHandler {
+
+ @Override
+ public void writeResponse(Object o, Type genericType, ServerRequestContext context)
+ throws WebApplicationException {
+
+ try (OutputStream stream = context.getOrCreateOutputStream()) {
+ stream.write(((String) o).getBytes());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+ }
+
+ @Provider
+ public static final class CustomStringMessageBodyWriter2 extends CustomStringMessageBodyWriter {
@Override
public void writeResponse(Object o, Type genericType, ServerRequestContext context)
diff --git a/extensions/undertow/deployment/src/main/java/io/quarkus/undertow/deployment/UndertowBuildStep.java b/extensions/undertow/deployment/src/main/java/io/quarkus/undertow/deployment/UndertowBuildStep.java
index 68f18b5765624..6758ef0245712 100644
--- a/extensions/undertow/deployment/src/main/java/io/quarkus/undertow/deployment/UndertowBuildStep.java
+++ b/extensions/undertow/deployment/src/main/java/io/quarkus/undertow/deployment/UndertowBuildStep.java
@@ -22,6 +22,7 @@
import javax.annotation.security.RunAs;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.SessionScoped;
+import javax.enterprise.inject.Typed;
import javax.inject.Inject;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
@@ -78,12 +79,14 @@
import org.jboss.metadata.web.spec.WebResourceCollectionMetaData;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
+import io.quarkus.arc.deployment.AnnotationsTransformerBuildItem;
import io.quarkus.arc.deployment.BeanContainerBuildItem;
import io.quarkus.arc.deployment.ConfigInjectionStaticInitBuildItem;
import io.quarkus.arc.deployment.ContextRegistrationPhaseBuildItem;
import io.quarkus.arc.deployment.ContextRegistrationPhaseBuildItem.ContextConfiguratorBuildItem;
import io.quarkus.arc.deployment.CustomScopeBuildItem;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
+import io.quarkus.arc.processor.AnnotationsTransformer;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.Feature;
@@ -142,6 +145,7 @@ public class UndertowBuildStep {
public static final DotName DECLARE_ROLES = DotName.createSimple(DeclareRoles.class.getName());
public static final DotName MULTIPART_CONFIG = DotName.createSimple(MultipartConfig.class.getName());
public static final DotName SERVLET_SECURITY = DotName.createSimple(ServletSecurity.class.getName());
+ public static final DotName TYPED = DotName.createSimple(Typed.class.getName());
protected static final String SERVLET_CONTAINER_INITIALIZER = "META-INF/services/javax.servlet.ServletContainerInitializer";
protected static final DotName HANDLES_TYPES = DotName.createSimple(HandlesTypes.class.getName());
@@ -335,6 +339,40 @@ private boolean hasSecurityCapability(final Capabilities capabilities) {
return capabilities.isCapabilityWithPrefixPresent(Capability.SECURITY);
}
+ @BuildStep
+ public void addTypedAnnotations(
+ BuildProducer annotationsTransformer) {
+
+ annotationsTransformer.produce(new io.quarkus.arc.deployment.AnnotationsTransformerBuildItem(
+ new AnnotationsTransformer() {
+
+ @Override
+ public boolean appliesTo(AnnotationTarget.Kind kind) {
+ return kind == AnnotationTarget.Kind.CLASS;
+ }
+
+ @Override
+ public void transform(TransformationContext context) {
+ ClassInfo clazz = context.getTarget().asClass();
+ if (clazz.declaredAnnotation(WEB_SERVLET) != null
+ || clazz.declaredAnnotation(WEB_FILTER) != null
+ || clazz.declaredAnnotation(WEB_LISTENER) != null) {
+ if (clazz.declaredAnnotation(TYPED) == null) {
+ // Add @Typed(MyResource.class)
+ context.transform().add(createTypedAnnotationInstance(clazz)).done();
+ }
+ }
+ }
+ }));
+ }
+
+ private AnnotationInstance createTypedAnnotationInstance(ClassInfo clazz) {
+ return AnnotationInstance.create(TYPED, clazz,
+ new AnnotationValue[] { AnnotationValue.createArrayValue("value",
+ new AnnotationValue[] { AnnotationValue.createClassValue("value",
+ Type.create(clazz.name(), Type.Kind.CLASS)) }) });
+ }
+
@Record(STATIC_INIT)
@BuildStep()
public ServletDeploymentManagerBuildItem build(List servlets,
diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java
index 71cfa5cf8cc6d..94230917eb52c 100644
--- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java
+++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java
@@ -241,20 +241,11 @@ public Supplier> instanceSupplier(Class type, Annotatio
qualifiers = new Annotation[] { Default.Literal.INSTANCE };
}
Set> resolvedBeans = resolved.getValue(new Resolvable(type, qualifiers));
- Set> filteredBean = resolvedBeans;
if (resolvedBeans.size() > 1) {
- //if there are multiple beans we look for an exact match
- //this method is only called with the exact type required
- //so ignoring subclasses is the correct behaviour
- filteredBean = new HashSet<>();
- for (InjectableBean> i : resolvedBeans) {
- if (i.getBeanClass().equals(type)) {
- filteredBean.add(i);
- }
- }
+ throw new AmbiguousResolutionException("Beans: " + resolvedBeans);
}
- InjectableBean bean = filteredBean.size() != 1 ? null
- : (InjectableBean) filteredBean.iterator().next();
+ InjectableBean bean = resolvedBeans.size() != 1 ? null
+ : (InjectableBean) resolvedBeans.iterator().next();
if (bean == null) {
return null;
}
diff --git a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/ResteasyReactiveDotNames.java b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/ResteasyReactiveDotNames.java
index 6c9a24d14986d..c86e07b6d04ac 100644
--- a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/ResteasyReactiveDotNames.java
+++ b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/ResteasyReactiveDotNames.java
@@ -25,6 +25,7 @@
import javax.annotation.Priority;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
+import javax.enterprise.inject.Typed;
import javax.enterprise.inject.Vetoed;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -166,6 +167,7 @@ public final class ResteasyReactiveDotNames {
public static final DotName DEFAULT_VALUE = DotName.createSimple(DefaultValue.class.getName());
public static final DotName NAME_BINDING = DotName.createSimple(NameBinding.class.getName());
public static final DotName VETOED = DotName.createSimple(Vetoed.class.getName());
+ public static final DotName TYPED = DotName.createSimple(Typed.class.getName());
public static final DotName APPLICATION_SCOPED = DotName.createSimple(ApplicationScoped.class.getName());
public static final DotName SINGLETON = DotName.createSimple(Singleton.class.getName());
public static final DotName REQUEST_SCOPED = DotName.createSimple(RequestScoped.class.getName());
From dfb8e542bf77f774ff3cf5cbd8b7e9ab048e06a8 Mon Sep 17 00:00:00 2001
From: Georgios Andrianakis
Date: Mon, 10 Oct 2022 11:17:19 +0300
Subject: [PATCH 2/3] Ensure that providers in RESTEasy Reactive common module
aren't discoverable. These providers are registered manually, but previously
because they were annotated with @Provider, they could be inadvertently
registered as application classes in some test cases (essentially if an
actual application class extended them).
Added note about sorting - this note is needed in order to folks debugging in the future
from going down the wrong path and having the TCK fail.
Fix ChunkedResponseTest to be spec compliant.
---
.../test/response/ChunkedResponseTest.java | 39 +++++++++++++------
.../reactive/common/core/Serialisers.java | 6 ++-
.../ServerBooleanMessageBodyHandler.java | 2 -
.../ServerByteArrayMessageBodyHandler.java | 2 -
.../ServerCharArrayMessageBodyHandler.java | 2 -
.../ServerCharacterMessageBodyHandler.java | 2 -
.../ServerDefaultTextPlainBodyHandler.java | 2 -
.../serialisers/ServerFileBodyHandler.java | 2 -
.../ServerFilePartBodyHandler.java | 2 -
.../ServerFormUrlEncodedProvider.java | 2 -
.../ServerInputStreamMessageBodyHandler.java | 2 -
.../ServerNumberMessageBodyHandler.java | 2 -
.../serialisers/ServerPathBodyHandler.java | 2 -
.../ServerPathPartBodyHandler.java | 2 -
.../ServerStringMessageBodyHandler.java | 2 -
15 files changed, 33 insertions(+), 38 deletions(-)
diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/response/ChunkedResponseTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/response/ChunkedResponseTest.java
index 1bd68e6a2d9bb..ae68349b887c2 100644
--- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/response/ChunkedResponseTest.java
+++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/response/ChunkedResponseTest.java
@@ -7,14 +7,21 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.UncheckedIOException;
+import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
+import java.nio.charset.StandardCharsets;
+import javax.annotation.Priority;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
+import javax.ws.rs.Priorities;
import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;
-import org.jboss.resteasy.reactive.server.providers.serialisers.ServerStringMessageBodyHandler;
+import org.jboss.resteasy.reactive.server.spi.ResteasyReactiveResourceInfo;
+import org.jboss.resteasy.reactive.server.spi.ServerMessageBodyWriter;
import org.jboss.resteasy.reactive.server.spi.ServerRequestContext;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.junit.jupiter.api.Test;
@@ -68,29 +75,39 @@ public String helloSmall() {
}
@Provider
- public static class CustomStringMessageBodyWriter extends ServerStringMessageBodyHandler {
+ public static class CustomStringMessageBodyWriter implements ServerMessageBodyWriter {
@Override
- public void writeResponse(Object o, Type genericType, ServerRequestContext context)
- throws WebApplicationException {
+ public boolean isWriteable(Class> type, Type genericType, ResteasyReactiveResourceInfo target, MediaType mediaType) {
+ return true;
+ }
- try (OutputStream stream = context.getOrCreateOutputStream()) {
- stream.write(((String) o).getBytes());
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
+ @Override
+ public void writeResponse(String o, Type genericType, ServerRequestContext context) throws WebApplicationException {
+ context.serverResponse().end(o);
+ }
+
+ public boolean isWriteable(Class> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return true;
+ }
+
+ public void writeTo(String o, Class> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap httpHeaders, OutputStream entityStream)
+ throws IOException, WebApplicationException {
+ entityStream.write(o.getBytes(StandardCharsets.UTF_8));
}
}
@Provider
+ @Priority(Priorities.USER + 1) // the spec says that when it comes to writers, higher number means higher priority...
public static final class CustomStringMessageBodyWriter2 extends CustomStringMessageBodyWriter {
@Override
- public void writeResponse(Object o, Type genericType, ServerRequestContext context)
+ public void writeResponse(String o, Type genericType, ServerRequestContext context)
throws WebApplicationException {
try (OutputStream stream = context.getOrCreateOutputStream()) {
- stream.write(((String) o).getBytes());
+ stream.write(o.getBytes());
} catch (IOException e) {
throw new UncheckedIOException(e);
}
diff --git a/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/Serialisers.java b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/Serialisers.java
index 3f0b755be1ab0..1f5020bae6a4b 100644
--- a/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/Serialisers.java
+++ b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/Serialisers.java
@@ -151,7 +151,11 @@ public List> findBuildTimeWriters(Class> entityType, Runt
}
}
- return toMessageBodyWriters(findResourceWriters(writers, klass, produces, runtimeType));
+
+ var resourceWriters = findResourceWriters(writers, klass, produces, runtimeType);
+ // we must NOT sort here because the spec mentions that the writers closer to the requested java type are tried first
+ // and the list has already been built up in this way
+ return toMessageBodyWriters(resourceWriters);
}
protected List findResourceWriters(QuarkusMultivaluedMap, ResourceWriter> writers, Class> klass,
diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerBooleanMessageBodyHandler.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerBooleanMessageBodyHandler.java
index 57c631c833a27..2be468dd0a7bf 100644
--- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerBooleanMessageBodyHandler.java
+++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerBooleanMessageBodyHandler.java
@@ -5,14 +5,12 @@
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
-import javax.ws.rs.ext.Provider;
import org.jboss.resteasy.reactive.common.providers.serialisers.BooleanMessageBodyHandler;
import org.jboss.resteasy.reactive.server.spi.ResteasyReactiveResourceInfo;
import org.jboss.resteasy.reactive.server.spi.ServerMessageBodyReader;
import org.jboss.resteasy.reactive.server.spi.ServerRequestContext;
-@Provider
public class ServerBooleanMessageBodyHandler extends BooleanMessageBodyHandler
implements ServerMessageBodyReader {
diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerByteArrayMessageBodyHandler.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerByteArrayMessageBodyHandler.java
index 179b7ad9d40a1..1c1072159d824 100644
--- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerByteArrayMessageBodyHandler.java
+++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerByteArrayMessageBodyHandler.java
@@ -5,7 +5,6 @@
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
-import javax.ws.rs.ext.Provider;
import org.jboss.resteasy.reactive.common.providers.serialisers.ByteArrayMessageBodyHandler;
import org.jboss.resteasy.reactive.common.providers.serialisers.MessageReaderUtil;
@@ -14,7 +13,6 @@
import org.jboss.resteasy.reactive.server.spi.ServerMessageBodyWriter;
import org.jboss.resteasy.reactive.server.spi.ServerRequestContext;
-@Provider
public class ServerByteArrayMessageBodyHandler extends ByteArrayMessageBodyHandler
implements ServerMessageBodyWriter, ServerMessageBodyReader {
diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerCharArrayMessageBodyHandler.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerCharArrayMessageBodyHandler.java
index d853248c25e62..ce54d00bc73d6 100644
--- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerCharArrayMessageBodyHandler.java
+++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerCharArrayMessageBodyHandler.java
@@ -5,7 +5,6 @@
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
-import javax.ws.rs.ext.Provider;
import org.jboss.resteasy.reactive.common.providers.serialisers.CharArrayMessageBodyHandler;
import org.jboss.resteasy.reactive.common.providers.serialisers.MessageReaderUtil;
@@ -14,7 +13,6 @@
import org.jboss.resteasy.reactive.server.spi.ServerMessageBodyWriter;
import org.jboss.resteasy.reactive.server.spi.ServerRequestContext;
-@Provider
public class ServerCharArrayMessageBodyHandler extends CharArrayMessageBodyHandler
implements ServerMessageBodyWriter, ServerMessageBodyReader {
diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerCharacterMessageBodyHandler.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerCharacterMessageBodyHandler.java
index 5b7bbef52b761..e96f0c7d8dc7e 100644
--- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerCharacterMessageBodyHandler.java
+++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerCharacterMessageBodyHandler.java
@@ -5,14 +5,12 @@
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
-import javax.ws.rs.ext.Provider;
import org.jboss.resteasy.reactive.common.providers.serialisers.CharacterMessageBodyHandler;
import org.jboss.resteasy.reactive.server.spi.ResteasyReactiveResourceInfo;
import org.jboss.resteasy.reactive.server.spi.ServerMessageBodyReader;
import org.jboss.resteasy.reactive.server.spi.ServerRequestContext;
-@Provider
public class ServerCharacterMessageBodyHandler extends CharacterMessageBodyHandler
implements ServerMessageBodyReader {
diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerDefaultTextPlainBodyHandler.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerDefaultTextPlainBodyHandler.java
index 9bf58af235dad..51779b09fe86e 100644
--- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerDefaultTextPlainBodyHandler.java
+++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerDefaultTextPlainBodyHandler.java
@@ -9,14 +9,12 @@
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import javax.ws.rs.ext.Provider;
import org.jboss.resteasy.reactive.common.providers.serialisers.DefaultTextPlainBodyHandler;
import org.jboss.resteasy.reactive.server.spi.ResteasyReactiveResourceInfo;
import org.jboss.resteasy.reactive.server.spi.ServerMessageBodyReader;
import org.jboss.resteasy.reactive.server.spi.ServerRequestContext;
-@Provider
@Consumes("text/plain")
public class ServerDefaultTextPlainBodyHandler extends DefaultTextPlainBodyHandler implements ServerMessageBodyReader
+ * As opposed to {@link #beanInstance(Class, Annotation...)}, this method does NOT follow CDI
+ * resolution rules and in case of ambiguous resolution performs a choice based on the class type parameter.
+ *
+ * @param type
+ * @param qualifiers
+ * @return a bean instance or {@code null} if no matching bean is found
+ */
+ @Deprecated
default T instance(Class type, Annotation... qualifiers) {
return instanceFactory(type, qualifiers).create().get();
}
@@ -31,6 +53,20 @@ default T instance(Class type, Annotation... qualifiers) {
* @param qualifiers
* @return a bean instance factory, never {@code null}
*/
+ Factory beanInstanceFactory(Class type, Annotation... qualifiers);
+
+ /**
+ * This method is deprecated and will be removed in future versions.
+ * Use {@link #beanInstanceFactory(Class, Annotation...)} instead.
+ *
+ * As opposed to {@link #beanInstanceFactory(Class, Annotation...)}, this method does NOT follow CDI
+ * resolution rules and in case of ambiguous resolution performs a choice based on the class type parameter.
+ *
+ * @param type
+ * @param qualifiers
+ * @return a bean instance factory, never {@code null}
+ */
+ @Deprecated
Factory instanceFactory(Class type, Annotation... qualifiers);
/**
diff --git a/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/BeanContainerImpl.java b/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/BeanContainerImpl.java
index a2b2d46495c41..de4a28e5c11df 100644
--- a/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/BeanContainerImpl.java
+++ b/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/BeanContainerImpl.java
@@ -21,9 +21,19 @@ public BeanContainerImpl(ArcContainer container) {
this.container = container;
}
+ @Override
+ public Factory beanInstanceFactory(Class type, Annotation... qualifiers) {
+ Supplier> handleSupplier = container.beanInstanceSupplier(type, qualifiers);
+ return createFactory(handleSupplier, type, qualifiers);
+ }
+
@Override
public Factory instanceFactory(Class type, Annotation... qualifiers) {
Supplier> handleSupplier = container.instanceSupplier(type, qualifiers);
+ return createFactory(handleSupplier, type, qualifiers);
+ }
+
+ private Factory createFactory(Supplier> handleSupplier, Class type, Annotation... qualifiers) {
if (handleSupplier == null) {
LOGGER.debugf(
"No matching bean found for type %s and qualifiers %s. The bean might have been marked as unused and removed during build.",
diff --git a/extensions/elytron-security/runtime/src/main/java/io/quarkus/elytron/security/runtime/ElytronRecorder.java b/extensions/elytron-security/runtime/src/main/java/io/quarkus/elytron/security/runtime/ElytronRecorder.java
index 1285e779a7486..a2ebff71bc80e 100644
--- a/extensions/elytron-security/runtime/src/main/java/io/quarkus/elytron/security/runtime/ElytronRecorder.java
+++ b/extensions/elytron-security/runtime/src/main/java/io/quarkus/elytron/security/runtime/ElytronRecorder.java
@@ -31,7 +31,7 @@ public void runLoadTask(Runnable runnable) {
}
public void setDomainForIdentityProvider(BeanContainer bc, RuntimeValue domain) {
- bc.instance(ElytronSecurityDomainManager.class).setDomain(domain.getValue());
+ bc.beanInstance(ElytronSecurityDomainManager.class).setDomain(domain.getValue());
}
/**
diff --git a/extensions/funqy/funqy-google-cloud-functions/runtime/src/main/java/io/quarkus/funqy/gcp/functions/FunqyCloudFunctionsBindingRecorder.java b/extensions/funqy/funqy-google-cloud-functions/runtime/src/main/java/io/quarkus/funqy/gcp/functions/FunqyCloudFunctionsBindingRecorder.java
index e643ac84819e4..4ae45066d22e2 100644
--- a/extensions/funqy/funqy-google-cloud-functions/runtime/src/main/java/io/quarkus/funqy/gcp/functions/FunqyCloudFunctionsBindingRecorder.java
+++ b/extensions/funqy/funqy-google-cloud-functions/runtime/src/main/java/io/quarkus/funqy/gcp/functions/FunqyCloudFunctionsBindingRecorder.java
@@ -32,7 +32,7 @@ public class FunqyCloudFunctionsBindingRecorder {
public void init(BeanContainer bc) {
beanContainer = bc;
- objectMapper = beanContainer.instance(ObjectMapper.class);
+ objectMapper = beanContainer.beanInstance(ObjectMapper.class);
for (FunctionInvoker invoker : FunctionRecorder.registry.invokers()) {
if (invoker.hasInput()) {
diff --git a/extensions/funqy/funqy-server-common/runtime/src/main/java/io/quarkus/funqy/runtime/FunctionConstructor.java b/extensions/funqy/funqy-server-common/runtime/src/main/java/io/quarkus/funqy/runtime/FunctionConstructor.java
index d6f2f25386c6e..56abc399ebcb6 100644
--- a/extensions/funqy/funqy-server-common/runtime/src/main/java/io/quarkus/funqy/runtime/FunctionConstructor.java
+++ b/extensions/funqy/funqy-server-common/runtime/src/main/java/io/quarkus/funqy/runtime/FunctionConstructor.java
@@ -14,7 +14,7 @@ public FunctionConstructor(Class cls) {
public T construct() {
if (factory == null)
- factory = CONTAINER.instanceFactory(cls);
+ factory = CONTAINER.beanInstanceFactory(cls);
return factory.create().get();
}
}
diff --git a/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/HibernateOrmRecorder.java b/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/HibernateOrmRecorder.java
index f5c22b8521543..31a74d5dabfad 100644
--- a/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/HibernateOrmRecorder.java
+++ b/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/HibernateOrmRecorder.java
@@ -92,7 +92,7 @@ public DataSourceTenantConnectionResolver get() {
}
public void startAllPersistenceUnits(BeanContainer beanContainer) {
- beanContainer.instance(JPAConfig.class).startAll();
+ beanContainer.beanInstance(JPAConfig.class).startAll();
}
public Supplier sessionFactorySupplier(String persistenceUnitName) {
diff --git a/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanRecorder.java b/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanRecorder.java
index 49f4466156a26..5534f9658d78c 100644
--- a/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanRecorder.java
+++ b/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanRecorder.java
@@ -11,7 +11,7 @@ public class InfinispanRecorder {
public BeanContainerListener configureInfinispan(@RelaxedValidation Properties properties) {
return container -> {
- InfinispanClientProducer instance = container.instance(InfinispanClientProducer.class);
+ InfinispanClientProducer instance = container.beanInstance(InfinispanClientProducer.class);
instance.configure(properties);
};
}
diff --git a/extensions/resteasy-classic/resteasy-common/runtime/src/main/java/io/quarkus/resteasy/common/runtime/QuarkusConstructorInjector.java b/extensions/resteasy-classic/resteasy-common/runtime/src/main/java/io/quarkus/resteasy/common/runtime/QuarkusConstructorInjector.java
index 218b5e6a3d6ef..df4ac2bf252a9 100644
--- a/extensions/resteasy-classic/resteasy-common/runtime/src/main/java/io/quarkus/resteasy/common/runtime/QuarkusConstructorInjector.java
+++ b/extensions/resteasy-classic/resteasy-common/runtime/src/main/java/io/quarkus/resteasy/common/runtime/QuarkusConstructorInjector.java
@@ -32,7 +32,7 @@ public Object construct(boolean unwrapAsync) {
if (factory != null) {
return factory.get().get();
}
- factory = Arc.container().instanceSupplier(this.ctor.getDeclaringClass());
+ factory = Arc.container().beanInstanceSupplier(this.ctor.getDeclaringClass());
if (factory == null) {
return delegate.construct(unwrapAsync);
}
@@ -45,7 +45,7 @@ public Object construct(HttpRequest request, HttpResponse response, boolean unwr
if (factory != null) {
return factory.get().get();
}
- factory = Arc.container().instanceSupplier(this.ctor.getDeclaringClass());
+ factory = Arc.container().beanInstanceSupplier(this.ctor.getDeclaringClass());
if (factory == null) {
return delegate.construct(request, response, unwrapAsync);
}
diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/runtime/src/main/java/io/quarkus/resteasy/reactive/common/runtime/ArcBeanFactory.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/runtime/src/main/java/io/quarkus/resteasy/reactive/common/runtime/ArcBeanFactory.java
index c44b8bb45458c..25656077526e0 100644
--- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/runtime/src/main/java/io/quarkus/resteasy/reactive/common/runtime/ArcBeanFactory.java
+++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/runtime/src/main/java/io/quarkus/resteasy/reactive/common/runtime/ArcBeanFactory.java
@@ -12,7 +12,7 @@ public class ArcBeanFactory implements BeanFactory {
public ArcBeanFactory(Class target, BeanContainer beanContainer) {
targetClassName = target.getName();
- factory = beanContainer.instanceFactory(target);
+ factory = beanContainer.beanInstanceFactory(target);
}
@Override
diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/ResteasyReactiveRecorder.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/ResteasyReactiveRecorder.java
index bff2c062d5962..b884ee5a741b8 100644
--- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/ResteasyReactiveRecorder.java
+++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/ResteasyReactiveRecorder.java
@@ -133,7 +133,7 @@ public RuntimeValue createDeployment(DeploymentInfo info,
}
CurrentRequestManager
- .setCurrentRequestInstance(new QuarkusCurrentRequest(beanContainer.instance(CurrentVertxRequest.class)));
+ .setCurrentRequestInstance(new QuarkusCurrentRequest(beanContainer.beanInstance(CurrentVertxRequest.class)));
BlockingOperationSupport.setIoThreadDetector(new BlockingOperationSupport.IOThreadDetector() {
@Override
diff --git a/extensions/security-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnRecorder.java b/extensions/security-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnRecorder.java
index ff44d478c63c8..72fe655cb61ba 100644
--- a/extensions/security-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnRecorder.java
+++ b/extensions/security-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnRecorder.java
@@ -32,9 +32,9 @@ public WebAuthnRecorder(RuntimeValue httpConfiguration, Runti
}
public void setupRoutes(BeanContainer beanContainer, RuntimeValue routerValue, String prefix) {
- WebAuthnSecurity security = beanContainer.instance(WebAuthnSecurity.class);
- WebAuthnAuthenticationMechanism authMech = beanContainer.instance(WebAuthnAuthenticationMechanism.class);
- IdentityProviderManager identityProviderManager = beanContainer.instance(IdentityProviderManager.class);
+ WebAuthnSecurity security = beanContainer.beanInstance(WebAuthnSecurity.class);
+ WebAuthnAuthenticationMechanism authMech = beanContainer.beanInstance(WebAuthnAuthenticationMechanism.class);
+ IdentityProviderManager identityProviderManager = beanContainer.beanInstance(IdentityProviderManager.class);
WebAuthnController controller = new WebAuthnController(security, config.getValue(), identityProviderManager, authMech);
Router router = routerValue.getValue();
BodyHandler bodyHandler = BodyHandler.create();
diff --git a/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLRecorder.java b/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLRecorder.java
index 8e634b0de9892..048ac5e65d622 100644
--- a/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLRecorder.java
+++ b/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLRecorder.java
@@ -26,7 +26,7 @@
public class SmallRyeGraphQLRecorder {
public RuntimeValue createExecutionService(BeanContainer beanContainer, Schema schema) {
- GraphQLProducer graphQLProducer = beanContainer.instance(GraphQLProducer.class);
+ GraphQLProducer graphQLProducer = beanContainer.beanInstance(GraphQLProducer.class);
GraphQLSchema graphQLSchema = graphQLProducer.initialize(schema);
return new RuntimeValue<>(graphQLSchema != null);
}
diff --git a/extensions/smallrye-metrics/runtime/src/main/java/io/quarkus/smallrye/metrics/runtime/SmallRyeMetricsRecorder.java b/extensions/smallrye-metrics/runtime/src/main/java/io/quarkus/smallrye/metrics/runtime/SmallRyeMetricsRecorder.java
index f087fc6124305..08966f4712840 100644
--- a/extensions/smallrye-metrics/runtime/src/main/java/io/quarkus/smallrye/metrics/runtime/SmallRyeMetricsRecorder.java
+++ b/extensions/smallrye-metrics/runtime/src/main/java/io/quarkus/smallrye/metrics/runtime/SmallRyeMetricsRecorder.java
@@ -194,7 +194,7 @@ public void createRegistries(BeanContainer container) {
//HACK: registration is done via statics, but cleanup is done via pre destroy
//however if the bean is not used it will not be created, so no cleanup will be done
//we force bean creation here to make sure the container can restart correctly
- container.instance(MetricRegistries.class).getApplicationRegistry();
+ container.beanInstance(MetricRegistries.class).getApplicationRegistry();
}
public void dropRegistriesAtShutdown(ShutdownContext shutdownContext) {
diff --git a/extensions/undertow/runtime/src/main/java/io/quarkus/undertow/runtime/UndertowDeploymentRecorder.java b/extensions/undertow/runtime/src/main/java/io/quarkus/undertow/runtime/UndertowDeploymentRecorder.java
index bcb9095df2ac4..0975c2cce33f4 100644
--- a/extensions/undertow/runtime/src/main/java/io/quarkus/undertow/runtime/UndertowDeploymentRecorder.java
+++ b/extensions/undertow/runtime/src/main/java/io/quarkus/undertow/runtime/UndertowDeploymentRecorder.java
@@ -252,7 +252,7 @@ public RuntimeValue registerServlet(RuntimeValue de
InstanceFactory extends Servlet> instanceFactory) throws Exception {
InstanceFactory extends Servlet> factory = instanceFactory != null ? instanceFactory
- : new QuarkusInstanceFactory(beanContainer.instanceFactory(servletClass));
+ : new QuarkusInstanceFactory(beanContainer.beanInstanceFactory(servletClass));
ServletInfo servletInfo = new ServletInfo(name, (Class extends Servlet>) servletClass,
factory);
deploymentInfo.getValue().addServlet(servletInfo);
@@ -304,7 +304,7 @@ public RuntimeValue registerFilter(RuntimeValue info
InstanceFactory extends Filter> instanceFactory) throws Exception {
InstanceFactory extends Filter> factory = instanceFactory != null ? instanceFactory
- : new QuarkusInstanceFactory(beanContainer.instanceFactory(filterClass));
+ : new QuarkusInstanceFactory(beanContainer.beanInstanceFactory(filterClass));
FilterInfo filterInfo = new FilterInfo(name, (Class extends Filter>) filterClass, factory);
info.getValue().addFilter(filterInfo);
filterInfo.setAsyncSupported(asyncSupported);
@@ -329,7 +329,7 @@ public void registerListener(RuntimeValue info, Class> listene
info.getValue()
.addListener(new ListenerInfo((Class extends EventListener>) listenerClass,
(InstanceFactory extends EventListener>) new QuarkusInstanceFactory<>(
- factory.instanceFactory(listenerClass))));
+ factory.beanInstanceFactory(listenerClass))));
}
public void addMimeMapping(RuntimeValue info, String extension,
@@ -457,7 +457,7 @@ public DeploymentManager bootServletContainer(RuntimeValue info,
info.getValue().setClassIntrospecter(new ClassIntrospecter() {
@Override
public InstanceFactory createInstanceFactory(Class clazz) throws NoSuchMethodException {
- BeanContainer.Factory res = beanContainer.instanceFactory(clazz);
+ BeanContainer.Factory res = beanContainer.beanInstanceFactory(clazz);
if (res == null) {
return defaultVal.createInstanceFactory(clazz);
}
diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityRecorder.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityRecorder.java
index f4ca987fb85a2..053aa4542fcd9 100644
--- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityRecorder.java
+++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityRecorder.java
@@ -241,7 +241,7 @@ public BeanContainerListener initPermissions(HttpBuildTimeConfig permissions,
return new BeanContainerListener() {
@Override
public void created(BeanContainer container) {
- container.instance(PathMatchingHttpSecurityPolicy.class).init(permissions, policies);
+ container.beanInstance(PathMatchingHttpSecurityPolicy.class).init(permissions, policies);
}
};
}
diff --git a/extensions/websockets/client/runtime/src/main/java/io/quarkus/websockets/client/runtime/WebsocketCoreRecorder.java b/extensions/websockets/client/runtime/src/main/java/io/quarkus/websockets/client/runtime/WebsocketCoreRecorder.java
index 93ed683e37a61..ca321461c596d 100644
--- a/extensions/websockets/client/runtime/src/main/java/io/quarkus/websockets/client/runtime/WebsocketCoreRecorder.java
+++ b/extensions/websockets/client/runtime/src/main/java/io/quarkus/websockets/client/runtime/WebsocketCoreRecorder.java
@@ -125,7 +125,7 @@ public RuntimeValue createServerContainer(BeanContaine
ServerWebSocketContainer container = serverContainerFactory.create(new ObjectIntrospecter() {
@Override
public ObjectFactory createInstanceFactory(Class clazz) {
- BeanContainer.Factory factory = beanContainer.instanceFactory(clazz);
+ BeanContainer.Factory factory = beanContainer.beanInstanceFactory(clazz);
return new ObjectFactory() {
@Override
public ObjectHandle createInstance() {
diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/ArcContainer.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/ArcContainer.java
index 6f778ca19e69a..19f49a9b2de57 100644
--- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/ArcContainer.java
+++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/ArcContainer.java
@@ -99,6 +99,21 @@ public interface ArcContainer {
* @param
* @return
*/
+ Supplier> beanInstanceSupplier(Class type, Annotation... qualifiers);
+
+ /**
+ * This method is deprecated and will be removed in future versions.
+ * Use {@link #beanInstanceSupplier(Class, Annotation...)} instead.
+ *
+ * As opposed to {@link #beanInstanceSupplier(Class, Annotation...)}, this method does NOT follow CDI
+ * resolution rules and in case of ambiguous resolution performs a choice based on the class type parameter.
+ *
+ * @param type
+ * @param qualifiers
+ * @return
+ * @param
+ */
+ @Deprecated
Supplier> instanceSupplier(Class type, Annotation... qualifiers);
/**
diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java
index 94230917eb52c..3c88386ab5925 100644
--- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java
+++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java
@@ -235,17 +235,41 @@ public InstanceHandle instance(Type type, Annotation... qualifiers) {
}
@SuppressWarnings("unchecked")
+ @Override
+ public Supplier> beanInstanceSupplier(Class type, Annotation... qualifiers) {
+ return createInstanceSupplier(false, type, qualifiers);
+ }
+
@Override
public Supplier> instanceSupplier(Class type, Annotation... qualifiers) {
+ return createInstanceSupplier(true, type, qualifiers);
+ }
+
+ private Supplier> createInstanceSupplier(boolean resolveAmbiguities, Class type,
+ Annotation... qualifiers) {
if (qualifiers == null || qualifiers.length == 0) {
qualifiers = new Annotation[] { Default.Literal.INSTANCE };
}
Set> resolvedBeans = resolved.getValue(new Resolvable(type, qualifiers));
+ Set> filteredBean = resolvedBeans;
if (resolvedBeans.size() > 1) {
- throw new AmbiguousResolutionException("Beans: " + resolvedBeans);
+ if (resolveAmbiguities) {
+ // this is non-standard CDI behavior that we momentarily keep to retain compatibility
+ // if there are multiple beans we look for an exact match
+ // this method is only called with the exact type required
+ // so ignoring subclasses is the correct behaviour
+ filteredBean = new HashSet<>();
+ for (InjectableBean> i : resolvedBeans) {
+ if (i.getBeanClass().equals(type)) {
+ filteredBean.add(i);
+ }
+ }
+ } else {
+ throw new AmbiguousResolutionException("Beans: " + resolvedBeans);
+ }
}
- InjectableBean bean = resolvedBeans.size() != 1 ? null
- : (InjectableBean) resolvedBeans.iterator().next();
+ InjectableBean bean = filteredBean.size() != 1 ? null
+ : (InjectableBean) filteredBean.iterator().next();
if (bean == null) {
return null;
}
diff --git a/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/TestRecorder.java b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/TestRecorder.java
index d7f90b7c5eb84..ae6cf57794b9a 100644
--- a/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/TestRecorder.java
+++ b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/TestRecorder.java
@@ -54,7 +54,7 @@ public void startRuntimeService(ShutdownContext shutdownContext, RuntimeValue