[cdi-dev] [JBoss JIRA] (CDI-516) Firing events with dynamic parameterized types

Antoine Sabot-Durand (JIRA) issues at jboss.org
Wed Apr 29 11:40:46 EDT 2015

     [ https://issues.jboss.org/browse/CDI-516?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Antoine Sabot-Durand updated CDI-516:
    Fix Version/s: 2.0 (discussion)

> Firing events with dynamic parameterized types
> ----------------------------------------------
>                 Key: CDI-516
>                 URL: https://issues.jboss.org/browse/CDI-516
>             Project: CDI Specification Issues
>          Issue Type: Feature Request
>          Components: Events
>    Affects Versions: 1.2.Final
>            Reporter: Antonin Stefanutti
>             Fix For: 2.0 (discussion)
> For the time being, either by using {{Event.select(...)}}, respectively {{BeanManager.fireEvent(...)}}, it is not possible to fire an event whose runtime type is a dynamic parameterized type, as specified in [The {{Event}} interface|http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#event]:
> {quote}
> If the container is unable to resolve the parameterized type of the event object, it uses the specified type to infer the parameterized type of the event types.
> If the runtime type of the event object contains an unresolvable type variable, an {{IllegalArgumentException}} is thrown.
> {quote}
> Respectively in [Firing an event|http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#bm_fire_event]:
> {quote}
> If the runtime type of the event object contains a type variable, an {{IllegalArgumentException}} is thrown.
> {quote}
> While, it is possible to pass a {{TypeLiteral}} to the {{Event.select(...)}} method, e.g.:
> {code}
> @Inject
> Event<Object> event;
> event.select(new TypeLiteral<String>() {});
> {code}
> It is not possible to pass a type variable known at runtime as the {{TypeLiteral}} class relies on the declared type variable and does not permit to override that behavior as the {{TypeLiteral.getType()}} method is declared {{final}}.
> Yet, there are use cases where that need is valid, for example:
> {code}
> <T> CdiEventEndpoint<T> cdiEventEndpoint(InjectionPoint ip, CamelContext context, @Any Event<Object> event) throws Exception {
>     // Represents the runtime type for T
>     Type type = ((ParameterizedType) ip.getType()).getActualTypeArguments()[0];
>     String uri = endpointUri(type, ip.getQualifiers());
>     if (context.hasEndpoint(uri) == null) {
>         // Work around to pass the dynamic type
>         TypeLiteral<T> literal = new TypeLiteral<T>() {};
>         for (Field field : TypeLiteral.class.getDeclaredFields()) {
>              if (field.getType().equals(Type.class)) {
>                 field.setAccessible(true);
>                 field.set(literal, type);
>                 break;
>             }
>         }
>         // Here we used the dynamic type
>         Event<T> typedEvent = event.select(literal, ip.getQualifiers().toArray(new Annotation[ip.getQualifiers().size()]));
>         context.addEndpoint(uri, new CdiEventEndpoint<>(typedEvent, uri, context));
>     }
>     return CamelContextHelper.getMandatoryEndpoint(context, uri, CdiEventEndpoint.class);
> }
> {code}
> In the example above, the {{TypeLiteral}} class could have a constructor taking the dynamic type as argument.
> Another alternative would be to enrich the {{BeanManager}} SPI with the following method:
> {code}
> public void fireEvent(Object event, Type type, Annotation... qualifiers);
> {code}
> That use case is taken from the [CDI event Camel endpoint|https://github.com/astefanutti/camel-cdi/blob/84426570bcd7815eb98f87b07739aa9ddfc44191/impl/src/main/java/org/apache/camel/cdi/CdiCamelFactory.java#L91] in the [Camel CDI extension|https://github.com/astefanutti/camel-cdi].

This message was sent by Atlassian JIRA

More information about the cdi-dev mailing list