Enabling programmatic/synthetic decorators added by extension

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Enabling programmatic/synthetic decorators added by extension

arjan tijms
Hi,

I'm trying to add decorators and/or interceptors to a Bean<T> that's added via an extension. There doesn't seem to be any way to add interceptors, but decorators seem almost possible.

I've added a decorator in the following way:


AnnotatedType<AutoApplySessionDecorator> annotatedType = beanManager.createAnnotatedType(AutoApplySessionDecorator.class);
        
BeanAttributes<AutoApplySessionDecorator> beanAttributes = beanManager.createBeanAttributes(annotatedType);
        
Bean<AutoApplySessionDecorator> bean = beanManager.createBean(beanAttributes, AutoApplySessionDecorator.class, beanManager.getInjectionTargetFactory(annotatedType));
        
afterBeanDiscovery.addBean(bean);

Where the "AutoApplySessionDecorator" is an existing (non-scanned) decorator just used as an example.


While this seems to work, the problem is with the enablement. @Priority is not processed in this way, since it's only read from an AnnotatedType that's been added to the deployment (see e.g. in Weld org.jboss.weld.bootstrap.BeanDeployer.processPriority(AnnotatedType<?>)).

beans.xml is not really an option here due to the static nature of that and the fact that the decorator needs to be enabled dynamically here, plus that the implementation class of the decorator is a detail I would not like to expose to the application.


Is there any other way to either enable a (synthetic) decorator programmatically, or to add Interceptors to a programmatically added Bean<T>?

Kind regards,
Arjan Tijms


_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.
Reply | Threaded
Open this post in threaded view
|

Re: Enabling programmatic/synthetic decorators added by extension

Mark Struberg
ProxyFactory…

I’m really thinking about introducing something like javax.proxy, maybe as own sub-spec PDF…

LieGrue,
strub


> Am 02.03.2016 um 16:31 schrieb arjan tijms <[hidden email]>:
>
> Hi,
>
> I'm trying to add decorators and/or interceptors to a Bean<T> that's added via an extension. There doesn't seem to be any way to add interceptors, but decorators seem almost possible.
>
> I've added a decorator in the following way:
>
>
> AnnotatedType<AutoApplySessionDecorator> annotatedType = beanManager.createAnnotatedType(AutoApplySessionDecorator.class);
>        
> BeanAttributes<AutoApplySessionDecorator> beanAttributes = beanManager.createBeanAttributes(annotatedType);
>        
> Bean<AutoApplySessionDecorator> bean = beanManager.createBean(beanAttributes, AutoApplySessionDecorator.class, beanManager.getInjectionTargetFactory(annotatedType));
>        
> afterBeanDiscovery.addBean(bean);
>
> Where the "AutoApplySessionDecorator" is an existing (non-scanned) decorator just used as an example.
>
>
> While this seems to work, the problem is with the enablement. @Priority is not processed in this way, since it's only read from an AnnotatedType that's been added to the deployment (see e.g. in Weld org.jboss.weld.bootstrap.BeanDeployer.processPriority(AnnotatedType<?>)).
>
> beans.xml is not really an option here due to the static nature of that and the fact that the decorator needs to be enabled dynamically here, plus that the implementation class of the decorator is a detail I would not like to expose to the application.
>
>
> Is there any other way to either enable a (synthetic) decorator programmatically, or to add Interceptors to a programmatically added Bean<T>?
>
> Kind regards,
> Arjan Tijms
>
> _______________________________________________
> cdi-dev mailing list
> [hidden email]
> https://lists.jboss.org/mailman/listinfo/cdi-dev
>
> Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.


_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.
Reply | Threaded
Open this post in threaded view
|

Re: Enabling programmatic/synthetic decorators added by extension

Romain Manni-Bucau
+1, seems it is the way to fix several issues without introducing a lot of new concepts/API and in term of technical stack it is just standardizing what is there.


Romain Manni-Bucau
@rmannibucau |  Blog | Github | LinkedIn | Tomitriber

2016-03-02 22:48 GMT+01:00 Mark Struberg <[hidden email]>:
ProxyFactory…

I’m really thinking about introducing something like javax.proxy, maybe as own sub-spec PDF…

LieGrue,
strub


> Am 02.03.2016 um 16:31 schrieb arjan tijms <[hidden email]>:
>
> Hi,
>
> I'm trying to add decorators and/or interceptors to a Bean<T> that's added via an extension. There doesn't seem to be any way to add interceptors, but decorators seem almost possible.
>
> I've added a decorator in the following way:
>
>
> AnnotatedType<AutoApplySessionDecorator> annotatedType = beanManager.createAnnotatedType(AutoApplySessionDecorator.class);
>
> BeanAttributes<AutoApplySessionDecorator> beanAttributes = beanManager.createBeanAttributes(annotatedType);
>
> Bean<AutoApplySessionDecorator> bean = beanManager.createBean(beanAttributes, AutoApplySessionDecorator.class, beanManager.getInjectionTargetFactory(annotatedType));
>
> afterBeanDiscovery.addBean(bean);
>
> Where the "AutoApplySessionDecorator" is an existing (non-scanned) decorator just used as an example.
>
>
> While this seems to work, the problem is with the enablement. @Priority is not processed in this way, since it's only read from an AnnotatedType that's been added to the deployment (see e.g. in Weld org.jboss.weld.bootstrap.BeanDeployer.processPriority(AnnotatedType<?>)).
>
> beans.xml is not really an option here due to the static nature of that and the fact that the decorator needs to be enabled dynamically here, plus that the implementation class of the decorator is a detail I would not like to expose to the application.
>
>
> Is there any other way to either enable a (synthetic) decorator programmatically, or to add Interceptors to a programmatically added Bean<T>?
>
> Kind regards,
> Arjan Tijms
>
> _______________________________________________
> cdi-dev mailing list
> [hidden email]
> https://lists.jboss.org/mailman/listinfo/cdi-dev
>
> Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.


_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.


_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.
Reply | Threaded
Open this post in threaded view
|

Re: Enabling programmatic/synthetic decorators added by extension

Thomas Andraschko
+1

in DeltaSpike we implemented an own mechanism + proxy to invoke interceptors for partial beans.
We will probably enhance this for such usecases or even producers: https://issues.apache.org/jira/browse/DELTASPIKE-1069


2016-03-02 22:51 GMT+01:00 Romain Manni-Bucau <[hidden email]>:
+1, seems it is the way to fix several issues without introducing a lot of new concepts/API and in term of technical stack it is just standardizing what is there.


Romain Manni-Bucau
@rmannibucau |  Blog | Github | LinkedIn | Tomitriber

2016-03-02 22:48 GMT+01:00 Mark Struberg <[hidden email]>:
ProxyFactory…

I’m really thinking about introducing something like javax.proxy, maybe as own sub-spec PDF…

LieGrue,
strub


> Am 02.03.2016 um 16:31 schrieb arjan tijms <[hidden email]>:
>
> Hi,
>
> I'm trying to add decorators and/or interceptors to a Bean<T> that's added via an extension. There doesn't seem to be any way to add interceptors, but decorators seem almost possible.
>
> I've added a decorator in the following way:
>
>
> AnnotatedType<AutoApplySessionDecorator> annotatedType = beanManager.createAnnotatedType(AutoApplySessionDecorator.class);
>
> BeanAttributes<AutoApplySessionDecorator> beanAttributes = beanManager.createBeanAttributes(annotatedType);
>
> Bean<AutoApplySessionDecorator> bean = beanManager.createBean(beanAttributes, AutoApplySessionDecorator.class, beanManager.getInjectionTargetFactory(annotatedType));
>
> afterBeanDiscovery.addBean(bean);
>
> Where the "AutoApplySessionDecorator" is an existing (non-scanned) decorator just used as an example.
>
>
> While this seems to work, the problem is with the enablement. @Priority is not processed in this way, since it's only read from an AnnotatedType that's been added to the deployment (see e.g. in Weld org.jboss.weld.bootstrap.BeanDeployer.processPriority(AnnotatedType<?>)).
>
> beans.xml is not really an option here due to the static nature of that and the fact that the decorator needs to be enabled dynamically here, plus that the implementation class of the decorator is a detail I would not like to expose to the application.
>
>
> Is there any other way to either enable a (synthetic) decorator programmatically, or to add Interceptors to a programmatically added Bean<T>?
>
> Kind regards,
> Arjan Tijms
>
> _______________________________________________
> cdi-dev mailing list
> [hidden email]
> https://lists.jboss.org/mailman/listinfo/cdi-dev
>
> Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.


_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.


_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.


_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.
Reply | Threaded
Open this post in threaded view
|

Re: Enabling programmatic/synthetic decorators added by extension

arjan tijms
ProxyFactory sounds like a perfect solution indeed.

I now got something working, more or less, emphasis on less.

I first make a "normal" (but effectively dummy) decorator with @Priority available:

@Decorator
@Priority(PLATFORM_BEFORE + 200)
public abstract class HttpAuthenticationBaseDecorator implements HttpAuthenticationMechanism, Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    @Delegate
    HttpAuthenticationMechanism delegateMechanism;

    @Override
    public AuthStatus validateRequest(HttpServletRequest request, HttpServletResponse response, HttpMessageContext httpMessageContext) throws AuthException {
        return delegateMechanism.validateRequest(request, response, httpMessageContext);
    }
   // ...
}


Then I create a "dynamic/programmatic" decorator:


public class DynamicHttpAuthenticationDecorator implements Decorator<HttpAuthenticationBaseDecorator> {

    private final Set<Type> types = new HashSet<Type>(asList(HttpAuthenticationBaseDecorator.class, Object.class));
    private final Set<Type> decoratedTypes = singleton(HttpAuthenticationMechanism.class);
    
    private final BeanManager beanManager;
    private final InjectionPoint decoratorInjectionPoint;
    private final Set<InjectionPoint> injectionPoints;

    public DynamicHttpAuthenticationDecorator(BeanManager beanManager) {
        
        decoratorInjectionPoint = new DecoratorInjectionPoint(
            HttpAuthenticationMechanism.class, 
            beanManager.createAnnotatedType(HttpAuthenticationBaseDecorator.class).getFields().iterator().next(), 
            this);
        
        injectionPoints = singleton(decoratorInjectionPoint);
        
        this.beanManager = beanManager;
    }

    public HttpAuthenticationBaseDecorator create(CreationalContext<HttpAuthenticationBaseDecorator> creationalContext) {
        return new AutoApplySessionDecorator(
            (HttpAuthenticationMechanism) beanManager.getInjectableReference(decoratorInjectionPoint, creationalContext));
    }

    public void destroy(HttpAuthenticationBaseDecorator instance, CreationalContext<HttpAuthenticationBaseDecorator> creationalContext) {
        creationalContext.release();
    }
    
    public Set<Type> getTypes() {
        return types;
    }
    
    public Set<Type> getDecoratedTypes() {
        return decoratedTypes;
    }
    
    public Class<?> getBeanClass() {
        return HttpAuthenticationBaseDecorator.class;
    }

    public Type getDelegateType() {
        return HttpAuthenticationMechanism.class;
    }

    public Set<InjectionPoint> getInjectionPoints() {
        return injectionPoints;
    }
}

This Decorator<T> "pretends" that it's for the dummy decorator, via the getTypes(), but in create() it returns another actual Decorator. Then I create the delegate injection point of that decorator by grabbing the @Delegate annotated field from the real decorator, wrapping that basically in an InjectionPoint and then using that later with beanManager#getInjectableReference.

Now after adding this via afterBeanDiscovery.addBean(new DynamicHttpAuthenticationDecorator(beanManager)), and it actually gets called at runtime (tested on Weld).

Disadvantages are a fixed priority and the fact that the dummy decorator is called as well.

Have to say that implementing the javax.enterprise.inject.spi.Decorator interface, especially the part for grabbing the @Delegate is quite non-obvious.

What do you think, is this guaranteed to work, or did I abuse the CDI APIs too much here?

Kind regards,
Arjan Tijms














On Wed, Mar 2, 2016 at 11:14 PM, Thomas Andraschko <[hidden email]> wrote:
+1

in DeltaSpike we implemented an own mechanism + proxy to invoke interceptors for partial beans.
We will probably enhance this for such usecases or even producers: https://issues.apache.org/jira/browse/DELTASPIKE-1069


2016-03-02 22:51 GMT+01:00 Romain Manni-Bucau <[hidden email]>:
+1, seems it is the way to fix several issues without introducing a lot of new concepts/API and in term of technical stack it is just standardizing what is there.


Romain Manni-Bucau
@rmannibucau |  Blog | Github | LinkedIn | Tomitriber

2016-03-02 22:48 GMT+01:00 Mark Struberg <[hidden email]>:
ProxyFactory…

I’m really thinking about introducing something like javax.proxy, maybe as own sub-spec PDF…

LieGrue,
strub


> Am 02.03.2016 um 16:31 schrieb arjan tijms <[hidden email]>:
>
> Hi,
>
> I'm trying to add decorators and/or interceptors to a Bean<T> that's added via an extension. There doesn't seem to be any way to add interceptors, but decorators seem almost possible.
>
> I've added a decorator in the following way:
>
>
> AnnotatedType<AutoApplySessionDecorator> annotatedType = beanManager.createAnnotatedType(AutoApplySessionDecorator.class);
>
> BeanAttributes<AutoApplySessionDecorator> beanAttributes = beanManager.createBeanAttributes(annotatedType);
>
> Bean<AutoApplySessionDecorator> bean = beanManager.createBean(beanAttributes, AutoApplySessionDecorator.class, beanManager.getInjectionTargetFactory(annotatedType));
>
> afterBeanDiscovery.addBean(bean);
>
> Where the "AutoApplySessionDecorator" is an existing (non-scanned) decorator just used as an example.
>
>
> While this seems to work, the problem is with the enablement. @Priority is not processed in this way, since it's only read from an AnnotatedType that's been added to the deployment (see e.g. in Weld org.jboss.weld.bootstrap.BeanDeployer.processPriority(AnnotatedType<?>)).
>
> beans.xml is not really an option here due to the static nature of that and the fact that the decorator needs to be enabled dynamically here, plus that the implementation class of the decorator is a detail I would not like to expose to the application.
>
>
> Is there any other way to either enable a (synthetic) decorator programmatically, or to add Interceptors to a programmatically added Bean<T>?
>
> Kind regards,
> Arjan Tijms
>
> _______________________________________________
> cdi-dev mailing list
> [hidden email]
> https://lists.jboss.org/mailman/listinfo/cdi-dev
>
> Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.


_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.


_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.


_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.


_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.
Reply | Threaded
Open this post in threaded view
|

Re: Enabling programmatic/synthetic decorators added by extension

arjan tijms
Hi,

Just wondering, has there been any progress made for this topic? 

Having the ability to dynamically add interceptors and/or add them when building a Bean<T> using the programmatic APIs would still be incredibly useful.

Kind regards,
Arjan Tijms


On Fri, Mar 4, 2016 at 5:18 PM, arjan tijms <[hidden email]> wrote:
ProxyFactory sounds like a perfect solution indeed.

I now got something working, more or less, emphasis on less.

I first make a "normal" (but effectively dummy) decorator with @Priority available:

@Decorator
@Priority(PLATFORM_BEFORE + 200)
public abstract class HttpAuthenticationBaseDecorator implements HttpAuthenticationMechanism, Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    @Delegate
    HttpAuthenticationMechanism delegateMechanism;

    @Override
    public AuthStatus validateRequest(HttpServletRequest request, HttpServletResponse response, HttpMessageContext httpMessageContext) throws AuthException {
        return delegateMechanism.validateRequest(request, response, httpMessageContext);
    }
   // ...
}


Then I create a "dynamic/programmatic" decorator:


public class DynamicHttpAuthenticationDecorator implements Decorator<HttpAuthenticationBaseDecorator> {

    private final Set<Type> types = new HashSet<Type>(asList(HttpAuthenticationBaseDecorator.class, Object.class));
    private final Set<Type> decoratedTypes = singleton(HttpAuthenticationMechanism.class);
    
    private final BeanManager beanManager;
    private final InjectionPoint decoratorInjectionPoint;
    private final Set<InjectionPoint> injectionPoints;

    public DynamicHttpAuthenticationDecorator(BeanManager beanManager) {
        
        decoratorInjectionPoint = new DecoratorInjectionPoint(
            HttpAuthenticationMechanism.class, 
            beanManager.createAnnotatedType(HttpAuthenticationBaseDecorator.class).getFields().iterator().next(), 
            this);
        
        injectionPoints = singleton(decoratorInjectionPoint);
        
        this.beanManager = beanManager;
    }

    public HttpAuthenticationBaseDecorator create(CreationalContext<HttpAuthenticationBaseDecorator> creationalContext) {
        return new AutoApplySessionDecorator(
            (HttpAuthenticationMechanism) beanManager.getInjectableReference(decoratorInjectionPoint, creationalContext));
    }

    public void destroy(HttpAuthenticationBaseDecorator instance, CreationalContext<HttpAuthenticationBaseDecorator> creationalContext) {
        creationalContext.release();
    }
    
    public Set<Type> getTypes() {
        return types;
    }
    
    public Set<Type> getDecoratedTypes() {
        return decoratedTypes;
    }
    
    public Class<?> getBeanClass() {
        return HttpAuthenticationBaseDecorator.class;
    }

    public Type getDelegateType() {
        return HttpAuthenticationMechanism.class;
    }

    public Set<InjectionPoint> getInjectionPoints() {
        return injectionPoints;
    }
}

This Decorator<T> "pretends" that it's for the dummy decorator, via the getTypes(), but in create() it returns another actual Decorator. Then I create the delegate injection point of that decorator by grabbing the @Delegate annotated field from the real decorator, wrapping that basically in an InjectionPoint and then using that later with beanManager#getInjectableReference.

Now after adding this via afterBeanDiscovery.addBean(new DynamicHttpAuthenticationDecorator(beanManager)), and it actually gets called at runtime (tested on Weld).

Disadvantages are a fixed priority and the fact that the dummy decorator is called as well.

Have to say that implementing the javax.enterprise.inject.spi.Decorator interface, especially the part for grabbing the @Delegate is quite non-obvious.

What do you think, is this guaranteed to work, or did I abuse the CDI APIs too much here?

Kind regards,
Arjan Tijms














On Wed, Mar 2, 2016 at 11:14 PM, Thomas Andraschko <[hidden email]> wrote:
+1

in DeltaSpike we implemented an own mechanism + proxy to invoke interceptors for partial beans.
We will probably enhance this for such usecases or even producers: https://issues.apache.org/jira/browse/DELTASPIKE-1069


2016-03-02 22:51 GMT+01:00 Romain Manni-Bucau <[hidden email]>:
+1, seems it is the way to fix several issues without introducing a lot of new concepts/API and in term of technical stack it is just standardizing what is there.


Romain Manni-Bucau
@rmannibucau |  Blog | Github | LinkedIn | Tomitriber

2016-03-02 22:48 GMT+01:00 Mark Struberg <[hidden email]>:
ProxyFactory…

I’m really thinking about introducing something like javax.proxy, maybe as own sub-spec PDF…

LieGrue,
strub


> Am 02.03.2016 um 16:31 schrieb arjan tijms <[hidden email]>:
>
> Hi,
>
> I'm trying to add decorators and/or interceptors to a Bean<T> that's added via an extension. There doesn't seem to be any way to add interceptors, but decorators seem almost possible.
>
> I've added a decorator in the following way:
>
>
> AnnotatedType<AutoApplySessionDecorator> annotatedType = beanManager.createAnnotatedType(AutoApplySessionDecorator.class);
>
> BeanAttributes<AutoApplySessionDecorator> beanAttributes = beanManager.createBeanAttributes(annotatedType);
>
> Bean<AutoApplySessionDecorator> bean = beanManager.createBean(beanAttributes, AutoApplySessionDecorator.class, beanManager.getInjectionTargetFactory(annotatedType));
>
> afterBeanDiscovery.addBean(bean);
>
> Where the "AutoApplySessionDecorator" is an existing (non-scanned) decorator just used as an example.
>
>
> While this seems to work, the problem is with the enablement. @Priority is not processed in this way, since it's only read from an AnnotatedType that's been added to the deployment (see e.g. in Weld org.jboss.weld.bootstrap.BeanDeployer.processPriority(AnnotatedType<?>)).
>
> beans.xml is not really an option here due to the static nature of that and the fact that the decorator needs to be enabled dynamically here, plus that the implementation class of the decorator is a detail I would not like to expose to the application.
>
>
> Is there any other way to either enable a (synthetic) decorator programmatically, or to add Interceptors to a programmatically added Bean<T>?
>
> Kind regards,
> Arjan Tijms
>
> _______________________________________________
> cdi-dev mailing list
> [hidden email]
> https://lists.jboss.org/mailman/listinfo/cdi-dev
>
> Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.


_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.


_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.


_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.



_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.
Reply | Threaded
Open this post in threaded view
|

Re: Enabling programmatic/synthetic decorators added by extension

Martin Kouba
For the record - in CDI 2.0 we have
javax.enterprise.inject.spi.Prioritized interface (currently used for
ObserverMethod).

But since Weld 3.0.0.Alpha13 prioritized custom beans, interceptors and
decorators are also supported, i.e. Weld treats them as if annotated
with @Priority (see also WELD-2000 [1]). I think this approach is also
worth standardizing.

Martin

[1]
https://issues.jboss.org/browse/WELD-2000

Dne 26.7.2016 v 11:59 arjan tijms napsal(a):

> Hi,
>
> Just wondering, has there been any progress made for this topic?
>
> Having the ability to dynamically add interceptors and/or add them when
> building a Bean<T> using the programmatic APIs would still be incredibly
> useful.
>
> Kind regards,
> Arjan Tijms
>
>
> On Fri, Mar 4, 2016 at 5:18 PM, arjan tijms <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     ProxyFactory sounds like a perfect solution indeed.
>
>     I now got something working, more or less, emphasis on less.
>
>     I first make a "normal" (but effectively dummy) decorator with
>     @Priority available:
>
>     @Decorator
>     @Priority(PLATFORM_BEFORE + 200)
>     public abstract class HttpAuthenticationBaseDecorator implements
>     HttpAuthenticationMechanism, Serializable {
>
>         private static final long serialVersionUID = 1L;
>
>         @Inject
>         @Delegate
>         HttpAuthenticationMechanism delegateMechanism;
>
>         @Override
>         public AuthStatus validateRequest(HttpServletRequest request,
>     HttpServletResponse response, HttpMessageContext httpMessageContext)
>     throws AuthException {
>             return delegateMechanism.validateRequest(request, response,
>     httpMessageContext);
>         }
>        // ...
>     }
>
>
>     Then I create a "dynamic/programmatic" decorator:
>
>
>     public class DynamicHttpAuthenticationDecorator implements
>     Decorator<HttpAuthenticationBaseDecorator> {
>
>         private final Set<Type> types = new
>     HashSet<Type>(asList(HttpAuthenticationBaseDecorator.class,
>     Object.class));
>         private final Set<Type> decoratedTypes =
>     singleton(HttpAuthenticationMechanism.class);
>
>         private final BeanManager beanManager;
>         private final InjectionPoint decoratorInjectionPoint;
>         private final Set<InjectionPoint> injectionPoints;
>
>         public DynamicHttpAuthenticationDecorator(BeanManager beanManager) {
>
>             decoratorInjectionPoint = new DecoratorInjectionPoint(
>                 HttpAuthenticationMechanism.class,
>
>     beanManager.createAnnotatedType(HttpAuthenticationBaseDecorator.class).getFields().iterator().next(),
>                 this);
>
>             injectionPoints = singleton(decoratorInjectionPoint);
>
>             this.beanManager = beanManager;
>         }
>
>         public HttpAuthenticationBaseDecorator
>     create(CreationalContext<HttpAuthenticationBaseDecorator>
>     creationalContext) {
>             return new AutoApplySessionDecorator(
>                 (HttpAuthenticationMechanism)
>     beanManager.getInjectableReference(decoratorInjectionPoint,
>     creationalContext));
>         }
>
>         public void destroy(HttpAuthenticationBaseDecorator instance,
>     CreationalContext<HttpAuthenticationBaseDecorator> creationalContext) {
>             creationalContext.release();
>         }
>
>         public Set<Type> getTypes() {
>             return types;
>         }
>
>         public Set<Type> getDecoratedTypes() {
>             return decoratedTypes;
>         }
>
>         public Class<?> getBeanClass() {
>             return HttpAuthenticationBaseDecorator.class;
>         }
>
>         public Type getDelegateType() {
>             return HttpAuthenticationMechanism.class;
>         }
>
>         public Set<InjectionPoint> getInjectionPoints() {
>             return injectionPoints;
>         }
>     }
>
>     This Decorator<T> "pretends" that it's for the dummy decorator, via
>     the getTypes(), but in create() it returns another actual Decorator.
>     Then I create the delegate injection point of that decorator by
>     grabbing the @Delegate annotated field from the real decorator,
>     wrapping that basically in an InjectionPoint and then using that
>     later with beanManager#getInjectableReference.
>
>     Now after adding this via afterBeanDiscovery.addBean(new
>     DynamicHttpAuthenticationDecorator(beanManager)), and it actually
>     gets called at runtime (tested on Weld).
>
>     Disadvantages are a fixed priority and the fact that the dummy
>     decorator is called as well.
>
>     Have to say that implementing
>     the javax.enterprise.inject.spi.Decorator interface, especially the
>     part for grabbing the @Delegate is quite non-obvious.
>
>     What do you think, is this guaranteed to work, or did I abuse the
>     CDI APIs too much here?
>
>     Kind regards,
>     Arjan Tijms
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>     On Wed, Mar 2, 2016 at 11:14 PM, Thomas Andraschko
>     <[hidden email] <mailto:[hidden email]>>
>     wrote:
>
>         +1
>
>         in DeltaSpike we implemented an own mechanism + proxy to invoke
>         interceptors for partial beans.
>         We will probably enhance this for such usecases or even
>         producers: https://issues.apache.org/jira/browse/DELTASPIKE-1069
>
>
>         2016-03-02 22:51 GMT+01:00 Romain Manni-Bucau
>         <[hidden email] <mailto:[hidden email]>>:
>
>             +1, seems it is the way to fix several issues without
>             introducing a lot of new concepts/API and in term of
>             technical stack it is just standardizing what is there.
>
>
>             Romain Manni-Bucau
>             @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>             <http://rmannibucau.wordpress.com> | Github
>             <https://github.com/rmannibucau> | LinkedIn
>             <https://www.linkedin.com/in/rmannibucau> | Tomitriber
>             <http://www.tomitribe.com>
>
>             2016-03-02 22:48 GMT+01:00 Mark Struberg <[hidden email]
>             <mailto:[hidden email]>>:
>
>                 ProxyFactory…
>
>                 I’m really thinking about introducing something like
>                 javax.proxy, maybe as own sub-spec PDF…
>
>                 LieGrue,
>                 strub
>
>
>                 > Am 02.03.2016 um 16:31 schrieb arjan tijms
>                 <[hidden email] <mailto:[hidden email]>>:
>                 >
>                 > Hi,
>                 >
>                 > I'm trying to add decorators and/or interceptors to a
>                 Bean<T> that's added via an extension. There doesn't
>                 seem to be any way to add interceptors, but decorators
>                 seem almost possible.
>                 >
>                 > I've added a decorator in the following way:
>                 >
>                 >
>                 > AnnotatedType<AutoApplySessionDecorator> annotatedType
>                 =
>                 beanManager.createAnnotatedType(AutoApplySessionDecorator.class);
>                 >
>                 > BeanAttributes<AutoApplySessionDecorator>
>                 beanAttributes =
>                 beanManager.createBeanAttributes(annotatedType);
>                 >
>                 > Bean<AutoApplySessionDecorator> bean =
>                 beanManager.createBean(beanAttributes,
>                 AutoApplySessionDecorator.class,
>                 beanManager.getInjectionTargetFactory(annotatedType));
>                 >
>                 > afterBeanDiscovery.addBean(bean);
>                 >
>                 > Where the "AutoApplySessionDecorator" is an existing
>                 (non-scanned) decorator just used as an example.
>                 >
>                 >
>                 > While this seems to work, the problem is with the
>                 enablement. @Priority is not processed in this way,
>                 since it's only read from an AnnotatedType that's been
>                 added to the deployment (see e.g. in Weld
>                 org.jboss.weld.bootstrap.BeanDeployer.processPriority(AnnotatedType<?>)).
>                 >
>                 > beans.xml is not really an option here due to the
>                 static nature of that and the fact that the decorator
>                 needs to be enabled dynamically here, plus that the
>                 implementation class of the decorator is a detail I
>                 would not like to expose to the application.
>                 >
>                 >
>                 > Is there any other way to either enable a (synthetic)
>                 decorator programmatically, or to add Interceptors to a
>                 programmatically added Bean<T>?
>                 >
>                 > Kind regards,
>                 > Arjan Tijms
>                 >
>                 > _______________________________________________
>                 > cdi-dev mailing list
>                 > [hidden email] <mailto:[hidden email]>
>                 > https://lists.jboss.org/mailman/listinfo/cdi-dev
>                 >
>                 > Note that for all code provided on this list, the
>                 provider licenses the code under the Apache License,
>                 Version 2
>                 (http://www.apache.org/licenses/LICENSE-2.0.html). For
>                 all other ideas provided on this list, the provider
>                 waives all patent and other intellectual property rights
>                 inherent in such information.
>
>
>                 _______________________________________________
>                 cdi-dev mailing list
>                 [hidden email] <mailto:[hidden email]>
>                 https://lists.jboss.org/mailman/listinfo/cdi-dev
>
>                 Note that for all code provided on this list, the
>                 provider licenses the code under the Apache License,
>                 Version 2
>                 (http://www.apache.org/licenses/LICENSE-2.0.html). For
>                 all other ideas provided on this list, the provider
>                 waives all patent and other intellectual property rights
>                 inherent in such information.
>
>
>
>             _______________________________________________
>             cdi-dev mailing list
>             [hidden email] <mailto:[hidden email]>
>             https://lists.jboss.org/mailman/listinfo/cdi-dev
>
>             Note that for all code provided on this list, the provider
>             licenses the code under the Apache License, Version 2
>             (http://www.apache.org/licenses/LICENSE-2.0.html). For all
>             other ideas provided on this list, the provider waives all
>             patent and other intellectual property rights inherent in
>             such information.
>
>
>
>         _______________________________________________
>         cdi-dev mailing list
>         [hidden email] <mailto:[hidden email]>
>         https://lists.jboss.org/mailman/listinfo/cdi-dev
>
>         Note that for all code provided on this list, the provider
>         licenses the code under the Apache License, Version 2
>         (http://www.apache.org/licenses/LICENSE-2.0.html). For all other
>         ideas provided on this list, the provider waives all patent and
>         other intellectual property rights inherent in such information.
>
>
>
>
>
> _______________________________________________
> cdi-dev mailing list
> [hidden email]
> https://lists.jboss.org/mailman/listinfo/cdi-dev
>
> Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.
>

--
Martin Kouba
Software Engineer
Red Hat, Czech Republic
_______________________________________________
cdi-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/cdi-dev

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.