[cdi-dev] [JBoss JIRA] (CDI-686) Could InterceptionFactory accept an interface as type parameter

Xavier Dury (JIRA) issues at jboss.org
Wed Sep 12 08:13:01 EDT 2018

    [ https://issues.jboss.org/browse/CDI-686?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13632340#comment-13632340 ] 

Xavier Dury commented on CDI-686:

On my project, {{@Produces}} is used to integrate objects which are not CDI-aware (coming from other pure java libraries) with CDI beans as long as they provide an interface if they need to be proxied ({{@ApplicationScoped}}).

The only problem I had before CDI 2.0 was that it wasn't possible to apply {{@Interceptor}} on those objects.

I thought that {{InterceptionFactory}} would fix the problem but the fact that it can't be parameterized with an interface is very limiting.

My use-case is the following:

public interface ExternalService {
	/* some methods */

/* This implementation is not a CDI-bean, it is final (cannot be proxied) and has no default constructor or @Injected constructor. */
public final class ExternalServiceImplementation implements ExternalService {
	public ExternalServiceImplementation(/* some dependencies */) { ... }
	/* methods implementations */

public class Integrator {
	@Produces @ApplicationScoped
	public ExternalService externalService(/* some dependencies */) {
		return new ExternalServiceImplementation(/* some dependencies */);
		// This works as a proxy is created from the interface, not the implementation's class

Now, if I want to add transaction management to my object, I would change my code to:

public class Integrator {
	@Produces @ApplicationScoped
	public ExternalService externalService(InterceptionFactory<ExternalService> factory, /* some dependencies */) {
		factory.configure().add(new TransactionalLiteral());
		return factory.createInterceptedInstance(new ExternalServiceImplementation(/* some dependencies */));

But this does not work with the following message (in Weld):

WELD-001711: InterceptionFactory is not supported on interfaces. Check InterceptionFactory<external.ExternalService>

If I declare InterceptionFactory<ExternalServiceImplementation> instead, I get the following error:

WELD-001437: Bean type class external.ExternalServiceImplementation is not proxyable because it is final

> Could InterceptionFactory accept an interface as type parameter
> ---------------------------------------------------------------
>                 Key: CDI-686
>                 URL: https://issues.jboss.org/browse/CDI-686
>             Project: CDI Specification Issues
>          Issue Type: Clarification
>    Affects Versions: 2.0 .Final
>            Reporter: Antoine Sabot-Durand
>            Assignee: Antoine Sabot-Durand
>             Fix For: 2.0 .Final
> If you take this code:
> {code:java}
>     @Produces
>     public List<Object> produceList(InterceptionFactory<List<Object>> interceptionFactory) {
>         interceptionFactory.ignoreFinalMethods().configure().filterMethods((m) -> {
>             if (m.getJavaMember().getName().equals("add")
>                     && m.getJavaMember().getParameterCount() == 1) {
>                 return true;
>             }
>             return false;
>         }).findFirst().get().add(Monitor.Literal.INSTANCE);
>         return interceptionFactory.createInterceptedInstance(new ArrayList<>());
>     }
> {code}
> Parameterized type for injected {{InterceptionFactory}} is an interface {{List<Object>}}, so when calling {{configure()}}, user will work with an {{AnnotatedTypeConfigurator<List<Object>>}} to apply interceptor binding.
> In a standard interceptor usage, interceptor binding on interface are ignored (even if they have {{@Inherited}} annotation), so doing it with {{InterceptionFactory}} could be confusing for some user.

This message was sent by Atlassian JIRA

More information about the cdi-dev mailing list