-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
Hi @mkouba,
This is in regards to the problem I described on Zulip. Let me elaborate on this a little more. I have a test bean where I inject qualified injectees:
package org.acme.quickstart2;
import static org.assertj.core.api.Assertions.assertThat;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.junit.jupiter.api.Test;
import io.quarkus.test.junit.QuarkusTest;
@Singleton
@QuarkusTest
public class BuuTest {
@Inject
@BuuQualifier("foo")
BuuRef ref1;
@Inject
@BuuQualifier("bar")
BuuRef ref2;
@Test
void test_injectQualifiedDependentBeans() {
assertThat(ref1).isNotNull();
assertThat(ref2).isNotNull();
assertThat(ref1).isNotSameAs(ref2);
}
}
And I have a factory which produces these qualified injectees:
package org.acme.quickstart2;
import java.lang.annotation.Annotation;
import java.util.Set;
import javax.enterprise.context.Dependent;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.inject.Singleton;
import io.quarkus.arc.CurrentInjectionPointProvider;
@Singleton
public class BuuRefFactory {
@Produces
@Dependent
@BuuQualifier
public BuuRef create(final InjectionPoint injection) {
final BuuQualifier qualifier = getQualifier(injection);
final String name = qualifier.value();
return new BuuRef(name);
}
private BuuQualifier getQualifier(final InjectionPoint injection) {
final Set<Annotation> qualifiers = injection.getQualifiers();
for (Annotation qualifier : injection.getQualifiers()) {
if (qualifier instanceof BuuQualifier) {
return (BuuQualifier) qualifier;
}
}
throw new IllegalStateException("Qualifier not found in a set " + qualifiers);
}
}
My qualifier is the following and is special in a way that it has a @Nonbinding
value definition (not sure if this is important) in order to bind my producer to BuuRef
beans, but without exact qualification values matching:
package org.acme.quickstart2;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.enterprise.util.Nonbinding;
import javax.inject.Qualifier;
@Qualifier
@Documented
@Target({ FIELD, METHOD })
@Retention(RUNTIME)
public @interface BuuQualifier {
@Nonbinding
String value() default "#UNKNOWN";
}
A BuuRef
is a very simple POJO:
package org.acme.quickstart2;
public class BuuRef {
private final String name;
public BuuRef(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
The problem lies in the fact that each time new BuuRef
is produced by a factory, the InjectionPoint
passed down in the argument is always the same instance, an EMPTY
object from CurrentInjectionPointProvider
.
I see valid InjectionPointImpl
being created, but these are never passed down to producer, which receives EMPTY
instead.
When you run above test against master 999-SNAPSHOT you should receive exception which indicates that no expected qualifier has been found in a set (which is empty by definition because it's EMPTY
object passed down to producer instead of valid InjectionPointImpl
):
throw new IllegalStateException("Qualifier not found in a set " + qualifiers);