admin管理员组

文章数量:1406918

I'm trying to use generics in synthetic bean creation.

I create a List<Class<?>> Using the following

        syntheticBeanProducer.produce( SyntheticBeanBuildItem.configure(List.class) .scope(Singleton.class) .addType(com.crv.jms.Util.createType()) .unremovable() .addQualifier().annotation(Identifier.class).addValue("value", name).done() .createWith( recorder.createSupportedEventTypesList(supportedEventTypes)) .unremovable() .done());

And then specify its need in another syntheticBeanProducer

                    syntheticBeanProducer.produce( SyntheticBeanBuildItem.configure(EventProducer.class) .addType(EventProducer.class) .scope(Singleton.class) .setRuntimeInit() .addInjectionPoint( com.crv.jms.Util.createType(), AnnotationInstance.builder(Identifier.class).add("value", name).build()) .addQualifier().annotation(Identifier.class).addValue("value", name).done() .createWith(recorder.createParallelEventProducer(name, topicName)) .unremovable() .done());

I would suspect that this would work. however it just gives the error.

[ERROR] HealthCheckTest.testHealth » Runtime java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors [error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: jakarta.enterprise.inject.spi.DeploymentException: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type java.util.List<java.lang.Class<?>> and qualifiers [@io.smallryemon.annotation.Identifier("test")]

  • synthetic injection point
  • declared on SYNTHETIC bean [types=[java.lang.Object, com.crv.jms.EventProducer], qualifiers=[@Any, @io.smallryemon.annotation.Identifier("test")], target=n/a] The following beans match by type, but none has matching qualifiers:
  • PRODUCER METHOD bean [types=[java.util.List, java.lang.Object], qualifiers=[@Any, @ConfigProperty], target=java.util.List producesListConfigProperty(jakarta.enterprise.inject.spi.InjectionPoint ip), declaringBean=io.smallrye.config.inject.ConfigProducer]

I am suspecting that something is wrong during the generation of the List<Class<?>>. Does anyone have any insights?

Kind regards, Jelmer

Update:

Here is a reproducer.

I'm trying to use generics in synthetic bean creation.

I create a List<Class<?>> Using the following

        syntheticBeanProducer.produce( SyntheticBeanBuildItem.configure(List.class) .scope(Singleton.class) .addType(com.crv.jms.Util.createType()) .unremovable() .addQualifier().annotation(Identifier.class).addValue("value", name).done() .createWith( recorder.createSupportedEventTypesList(supportedEventTypes)) .unremovable() .done());

And then specify its need in another syntheticBeanProducer

                    syntheticBeanProducer.produce( SyntheticBeanBuildItem.configure(EventProducer.class) .addType(EventProducer.class) .scope(Singleton.class) .setRuntimeInit() .addInjectionPoint( com.crv.jms.Util.createType(), AnnotationInstance.builder(Identifier.class).add("value", name).build()) .addQualifier().annotation(Identifier.class).addValue("value", name).done() .createWith(recorder.createParallelEventProducer(name, topicName)) .unremovable() .done());

I would suspect that this would work. however it just gives the error.

[ERROR] HealthCheckTest.testHealth » Runtime java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors [error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: jakarta.enterprise.inject.spi.DeploymentException: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type java.util.List<java.lang.Class<?>> and qualifiers [@io.smallryemon.annotation.Identifier("test")]

  • synthetic injection point
  • declared on SYNTHETIC bean [types=[java.lang.Object, com.crv.jms.EventProducer], qualifiers=[@Any, @io.smallryemon.annotation.Identifier("test")], target=n/a] The following beans match by type, but none has matching qualifiers:
  • PRODUCER METHOD bean [types=[java.util.List, java.lang.Object], qualifiers=[@Any, @ConfigProperty], target=java.util.List producesListConfigProperty(jakarta.enterprise.inject.spi.InjectionPoint ip), declaringBean=io.smallrye.config.inject.ConfigProducer]

I am suspecting that something is wrong during the generation of the List<Class<?>>. Does anyone have any insights?

Kind regards, Jelmer

Update:

Here is a reproducer.

https://github/jelmew/example_generic_problems

Share Improve this question edited Mar 10 at 9:27 jelmew asked Mar 6 at 13:36 jelmewjelmew 5851 gold badge7 silver badges15 bronze badges 2
  • 1 This looks like it should work on the first sight. Can you produce a minimal reproducer project somewhere on GitHub or the like? – Ladicek Commented Mar 7 at 9:57
  • I have a reproducer. You can see that just starting the dev mode fails. – jelmew Commented Mar 10 at 9:27
Add a comment  | 

1 Answer 1

Reset to default 1

I had to narrow down the reproducer and then step through the bean resolution process in the debugger, but the gist of it is: this behaves as expected, due to bean assignability rules in the CDI specification. Specifically, see https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#assignable_parameters

The main point is that a required type (on an injection point) can contain wildcards, but the bean type (on the bean definition) cannot. I'm not exactly sure why, but that's how it is. If the bean type contains a wildcard (even unbounded), the required type will not match even if the wildcard is identical.

The easiest fix would be to make the bean have a bean type of List<Class<Object>>. That doesn't necessarily work in practice, so probably the best would be to not use Class<?>, but the raw Class type -- both on the bean (as a bean type) and on the injection point (as a required type).

本文标签: Using generics in a quarkus buildstep not working as expected when creating a synthetic beanStack Overflow