[
https://issues.apache.org/jira/browse/OWB-1004?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14128588#comment-14128588
]
Antonin Stefanutti commented on OWB-1004:
-----------------------------------------
Hi Romain,
You can find one example of such a situation in the adapted version of the
Camel CDI component here: https://github.com/astefanutti/camel-cdi.
Basically, multiple {{CamelContext}} beans can be enabled in the CDI container
that are qualified with the {{@ContextName}} qualifier. For these Camel
contexts, I need to produce Camel objects like {{ProducerTemplate}} and
{{Endpoints}} corresponding to each of these contexts. This is a typical need
that shows in a lot of CDI extensions and from what I've seen there are
generally two ways to meet that need.
The first approach, the one the official Camel CDI implementation has chosen,
is to veto all the {{CamelContext}} beans and add a generic {{CamelContext}}
bean producer as a replacement. That way, {{ProducerTemplate}} and
{{Endpoints}} instances can be instantiated with a producer method that's not
qualified with the {{@ContextName}}. The trick is that the {{@ContextName}}
annotation is not a CDI qualifier because in that situation *it is not possible
to used that annotation both as a CDI qualifier and a metadata annotation* (in
that case the metadata being the Camel context name).
I'm using that first approach in the Dropwizard [Metrics CDI
extension|https://github.com/astefanutti/metrics-cdi] as Metrics comes with
annotations that are used as metadata and not added as qualifiers during the
container initialization. In that example, it's all fine given the dynamic
nature of the Metrics objects being handled, that is created for each
intercepted methods. IMO, that's quite the opposite for the Camel contexts
which are meant to be declared statically, thus the second approach...
The second, opposite, approach, and the one I've decided to use in the adapted
version of Camel CDI, to meet that use case yet avoiding the unnecessary
vetoing of the enabled {{CamelContext}} beans, is to collect all the
{{@ContextName}} qualifiers and decorated the {{BeanAttributes}} of the
{{ProducerTemplate}} and {{Endpoints}} producers with them. That way, I'm able
to used {{@ContextName}} both as a CDI qualifier and a metadata annotation.
Unfortunately, that leads to that issue while that works fine with Weld. The
additional benefit of that approach is that it relies on the standard typesafe
resolution mechanism during the deployment phase to detect for example a
{{@ContextName("ctxName") ProducerTemplate}} injection point while there is no
{{@ContextName("ctxName") CamelContext}} bean, which is not possible with the
first approach.
The second approach implementation is located here:
https://github.com/astefanutti/camel-cdi/blob/b4a44a7cc92af95c920ee1469ebdc3f43ecd3d53/impl/src/main/java/org/apache/camel/cdi/CdiCamelExtension.java
https://github.com/astefanutti/camel-cdi/blob/b4a44a7cc92af95c920ee1469ebdc3f43ecd3d53/impl/src/main/java/org/apache/camel/cdi/CdiCamelFactory.java
That's my understanding of the need. Other approaches probably exit.
> Enable repeatable qualifiers with binding attributes
> ----------------------------------------------------
>
> Key: OWB-1004
> URL: https://issues.apache.org/jira/browse/OWB-1004
> Project: OpenWebBeans
> Issue Type: Improvement
> Components: Core
> Affects Versions: 2.0.0
> Reporter: Antonin Stefanutti
>
> While having multiple annotations of the same type declared on a member or
> type is not permitted in the Java language prior to Java 8, the CDI
> specification does not set any particular restriction in its SPI that enables
> to alter bean metadata, e.g. in {{Annotated.getAnnotations()}} and
> {{BeanAttributes.getQualifiers()}}, in a way to add multiple annotations of
> the same type.
> Having multiple CDI qualifiers of the same type can prove to be useful when
> this type declares binding attributes.
> Unfortunately, in such situation, the following exception is thrown by OWB
> version 2.0-SNASHOT:
> {code}
> javax.enterprise.inject.spi.DefinitionException:
> java.lang.IllegalArgumentException: Manager.resolveDecorators() method
> parameter qualifiers array argument can not define duplicate qualifier
> annotation with name : @org.apache.camel.cdi.ContextName
> at
> org.apache.webbeans.config.BeansDeployer.deploy(BeansDeployer.java:284)
> at
> org.apache.webbeans.lifecycle.AbstractLifeCycle.bootstrapApplication(AbstractLifeCycle.java:138)
> at
> org.apache.webbeans.lifecycle.AbstractLifeCycle.startApplication(AbstractLifeCycle.java:104)
> at
> org.apache.webbeans.arquillian.standalone.OwbStandaloneContainer.deploy(OwbStandaloneContainer.java:122)
> {code}
> IMO, preventing the ability to add multiple annotations of the same type via
> the CDI SPI restricts powerful use cases (I can share more details on these
> use cases if needed). Last but not least, having this ability built-in in the
> Java 8 language is another incentive to provide that support.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)