[JBoss JIRA] (CDI-584) Clarification needed on Set mutability returned by SPI
by Antoine Sabot-Durand (JIRA)
[ https://issues.jboss.org/browse/CDI-584?page=com.atlassian.jira.plugin.sy... ]
Antoine Sabot-Durand commented on CDI-584:
------------------------------------------
To that I could answer, "what's the use of ProcessBean if you can't do anything about the bean tied to the event" ;) ?
But I have an example. I was asked to build a prototype extension to create an injection point when a given annotation ({{@CacheContext}}) is found on a field. Here's the portable code I had to wrote to create the feature :
* An AnnotatedType [implementation|https://github.com/antoinesd/CDI-Sandbox/blob/fb18eb718ab9...]
* An AnnotatedField [implementation|https://github.com/antoinesd/CDI-Sandbox/blob/fb18eb718ab9...]
* and the [Extension|https://github.com/antoinesd/CDI-Sandbox/blob/fb18eb718ab93f68d...]
Extension code is small but {{AnnotatedType}} and {{AnnotatedField }} are verbose and the whole is cumbersome to read and maintain (3 classes and 178 lines of code)
If we only target OWB, the extension code is:
{code}
package org.cdisandbox.autoinject.Extension;
import org.cdisandbox.autoinject.CacheContext;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.*;
import java.util.HashSet;
import java.util.Set;
/**
* Extension looking for the @CacheContext annotation to transform it in an InjectionPoint
*/
public class AutoInjectExtension implements Extension {
private Set<AnnotatedType<?>> atWithCacheContext = new HashSet<>();
/**
* This Observer captures all AnnotatedType containing @CacheContext
*/
public void CreateInjectionPoint(@Observes @WithAnnotations(CacheContext.class) ProcessAnnotatedType<?> pat) {
atWithCacheContext.add(pat.getAnnotatedType());
}
/**
* This observer add an injection point in all bean having @Cachecontext annotaion on some field
*/
public <T> void CheckBeansForCacheContext(@Observes ProcessManagedBean<T> pmb, BeanManager bm) {
AnnotatedType<T> beanAT = pmb.getAnnotatedBeanClass();
if(atWithCacheContext.contains(beanAT)) {
Bean<T> bean = pmb.getBean();
Set<InjectionPoint> ips = new HashSet(bean.getInjectionPoints());
for (AnnotatedField<? super T> f : beanAT.getFields()) {
if(f.isAnnotationPresent(CacheContext.class)) {
ips.add(bm.createInjectionPoint(f));
}
}
}
}
}
{code}
One class, 42 lines.
> Clarification needed on Set mutability returned by SPI
> ------------------------------------------------------
>
> Key: CDI-584
> URL: https://issues.jboss.org/browse/CDI-584
> Project: CDI Specification Issues
> Issue Type: Clarification
> Components: Portable Extensions
> Reporter: Antoine Sabot-Durand
>
> {{ProcessBean}} lifecycle event could be the occasion to add new Injection point to an existing bean, but when you call {{ProcessBean#getBean()#getInjectionPoints()}} the returned set is mutable in OWB and immutable in Weld.
> As the spec doesn't precise if the Set should be mutable or not, each impl made its own choice.
> The result is a lack of consistency between both impl and an interesting feature harder to do with Weld (work with AnnotatedType or create a custom bean to add injection point)
> More generally we should clarify mutability of each Set returned in the SPI. And check if it wouldn't be better to add method to life cycle event to provide a "temporary" mutable set (i.e. {{ProcessBean#getInjectionPoints()}}
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 10 months
[JBoss JIRA] (CDI-584) Clarification needed on Set mutability returned by SPI
by Martin Kouba (JIRA)
[ https://issues.jboss.org/browse/CDI-584?page=com.atlassian.jira.plugin.sy... ]
Martin Kouba commented on CDI-584:
----------------------------------
I'm sorry to be so sceptical but why do I need to add an injection point to a bean at this phase? A simple example would be enough.
> Clarification needed on Set mutability returned by SPI
> ------------------------------------------------------
>
> Key: CDI-584
> URL: https://issues.jboss.org/browse/CDI-584
> Project: CDI Specification Issues
> Issue Type: Clarification
> Components: Portable Extensions
> Reporter: Antoine Sabot-Durand
>
> {{ProcessBean}} lifecycle event could be the occasion to add new Injection point to an existing bean, but when you call {{ProcessBean#getBean()#getInjectionPoints()}} the returned set is mutable in OWB and immutable in Weld.
> As the spec doesn't precise if the Set should be mutable or not, each impl made its own choice.
> The result is a lack of consistency between both impl and an interesting feature harder to do with Weld (work with AnnotatedType or create a custom bean to add injection point)
> More generally we should clarify mutability of each Set returned in the SPI. And check if it wouldn't be better to add method to life cycle event to provide a "temporary" mutable set (i.e. {{ProcessBean#getInjectionPoints()}}
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 10 months
[JBoss JIRA] (CDI-584) Clarification needed on Set mutability returned by SPI
by Antoine Sabot-Durand (JIRA)
[ https://issues.jboss.org/browse/CDI-584?page=com.atlassian.jira.plugin.sy... ]
Antoine Sabot-Durand commented on CDI-584:
------------------------------------------
[~mkouba] agree with you, but, that means we should check if some Lifecycle events (like ProcessBean) could have new method to change the underlying meta-data (i.e {{ProcessBean#addInjectionPoint()}}).
[~rmannibucau] also agree. The idea is not to force OWB to change its behavior but to state that it's not portable. And we should provide standard way to perform these meta data mutation at the lifecycle event level (see my remark above).
> Clarification needed on Set mutability returned by SPI
> ------------------------------------------------------
>
> Key: CDI-584
> URL: https://issues.jboss.org/browse/CDI-584
> Project: CDI Specification Issues
> Issue Type: Clarification
> Components: Portable Extensions
> Reporter: Antoine Sabot-Durand
>
> {{ProcessBean}} lifecycle event could be the occasion to add new Injection point to an existing bean, but when you call {{ProcessBean#getBean()#getInjectionPoints()}} the returned set is mutable in OWB and immutable in Weld.
> As the spec doesn't precise if the Set should be mutable or not, each impl made its own choice.
> The result is a lack of consistency between both impl and an interesting feature harder to do with Weld (work with AnnotatedType or create a custom bean to add injection point)
> More generally we should clarify mutability of each Set returned in the SPI. And check if it wouldn't be better to add method to life cycle event to provide a "temporary" mutable set (i.e. {{ProcessBean#getInjectionPoints()}}
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 10 months
[JBoss JIRA] (CDI-527) allow proxying of classes with non-private final methods
by Romain Manni-Bucau (JIRA)
[ https://issues.jboss.org/browse/CDI-527?page=com.atlassian.jira.plugin.sy... ]
Romain Manni-Bucau commented on CDI-527:
----------------------------------------
[~mkouba] it is doable as generic as you mention of with a hardcoded list for known types depending the type of application. The main point is to allow this type of usage and to allow to solve the broken applications without modifying the existing code. The SPI solves the second point and the annotation the first one so sounds like a good compromise for past and future to me.
> allow proxying of classes with non-private final methods
> --------------------------------------------------------
>
> Key: CDI-527
> URL: https://issues.jboss.org/browse/CDI-527
> Project: CDI Specification Issues
> Issue Type: Feature Request
> Components: Beans
> Affects Versions: 1.2.Final
> Reporter: Mark Struberg
> Assignee: Mark Struberg
> Fix For: 2.0 (proposed)
>
>
> Currently we explicitly disallow proxying of classes with non-private final methods.
> EJB _does_ allow this. And there are a few final methods in the JDK and other libs. E.g. HashMap#initHashSeedAsNeeded. Currently we cannot have a producer method for it.
> We might rethink our decision and allow it. Probably with an own annotation like @AllowProxying which disables this check for certain cases (subclass managed-beans or producers).
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 10 months
[JBoss JIRA] (CDI-584) Clarification needed on Set mutability returned by SPI
by Romain Manni-Bucau (JIRA)
[ https://issues.jboss.org/browse/CDI-584?page=com.atlassian.jira.plugin.sy... ]
Romain Manni-Bucau commented on CDI-584:
----------------------------------------
Not sure in term of implementation but stating the user shouldnt modify it and it is not portable what happens if so sounds good.
> Clarification needed on Set mutability returned by SPI
> ------------------------------------------------------
>
> Key: CDI-584
> URL: https://issues.jboss.org/browse/CDI-584
> Project: CDI Specification Issues
> Issue Type: Clarification
> Components: Portable Extensions
> Reporter: Antoine Sabot-Durand
>
> {{ProcessBean}} lifecycle event could be the occasion to add new Injection point to an existing bean, but when you call {{ProcessBean#getBean()#getInjectionPoints()}} the returned set is mutable in OWB and immutable in Weld.
> As the spec doesn't precise if the Set should be mutable or not, each impl made its own choice.
> The result is a lack of consistency between both impl and an interesting feature harder to do with Weld (work with AnnotatedType or create a custom bean to add injection point)
> More generally we should clarify mutability of each Set returned in the SPI. And check if it wouldn't be better to add method to life cycle event to provide a "temporary" mutable set (i.e. {{ProcessBean#getInjectionPoints()}}
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 10 months
[JBoss JIRA] (CDI-527) allow proxying of classes with non-private final methods
by Martin Kouba (JIRA)
[ https://issues.jboss.org/browse/CDI-527?page=com.atlassian.jira.plugin.sy... ]
Martin Kouba commented on CDI-527:
----------------------------------
[~rmannibucau] Ok, so we would need a configurable extension which would detect problematic AnnotatedTypes and add this annotation where appropriate. Sounds doable. Also I'm aware of pros and cons of portable and non-portable solutions.
> allow proxying of classes with non-private final methods
> --------------------------------------------------------
>
> Key: CDI-527
> URL: https://issues.jboss.org/browse/CDI-527
> Project: CDI Specification Issues
> Issue Type: Feature Request
> Components: Beans
> Affects Versions: 1.2.Final
> Reporter: Mark Struberg
> Assignee: Mark Struberg
> Fix For: 2.0 (proposed)
>
>
> Currently we explicitly disallow proxying of classes with non-private final methods.
> EJB _does_ allow this. And there are a few final methods in the JDK and other libs. E.g. HashMap#initHashSeedAsNeeded. Currently we cannot have a producer method for it.
> We might rethink our decision and allow it. Probably with an own annotation like @AllowProxying which disables this check for certain cases (subclass managed-beans or producers).
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 10 months
[JBoss JIRA] (CDI-414) Support for "self" injection or intercepted self invocation
by Martin Kouba (JIRA)
[ https://issues.jboss.org/browse/CDI-414?page=com.atlassian.jira.plugin.sy... ]
Martin Kouba commented on CDI-414:
----------------------------------
{quote}
bq. Of course it IS used and sometimes needed. But for those occasions there is the well-known pattern of simply using self-injection manually.
IMO Self-Injection is not a design pattern, it's a smelly trick introduced to EJB implementation limitation
The number of average joe who think that interceptor will be triggered from internal call is countless. Check on Stack Overflow
{quote}
I'm not really sure this "feature" would help ordinary users, we would basically replace self-injection trick with annotation trick (of course, except it's easier to use) - the feature will be disabled by default, right? Also I'm not sure it's a good idea to reuse the {{@AllowProxy}} (or whatever the name would be) annotation.
> Support for "self" injection or intercepted self invocation
> -----------------------------------------------------------
>
> Key: CDI-414
> URL: https://issues.jboss.org/browse/CDI-414
> Project: CDI Specification Issues
> Issue Type: Bug
> Components: Resolution
> Reporter: arjan tijms
> Fix For: 2.0 (discussion)
>
>
> Many features of CDI and EJB work by means of a proxy that intercepts calls and adds 'aspects'. In Java it's however not possible to decorate the {{this}} pointer, so methods called on the same bean instance from within a method in the bean do not get their 'aspects' applied.
> This is a well known limitation, but in EJB it's possible to work around this by injecting a bean into itself. E.g.
> {code}
> @Stateless
> public class Foo {
> @EJB
> private Foo self;
> // ...
> }
> {code}
> Also see http://adam-bien.com/roller/abien/entry/how_to_self_invoke_ejb
> Unfortunately using CDI and {{@Inject}} this doesn't work. Weld for instance fails the deployment and logs:
> {noformat}
> WELD-001443 Pseudo scoped bean has circular dependencies.
> {noformat}
> See also: http://adam-bien.com/roller/abien/entry/inject_vs_ejb
> Although there are workarounds, it would be great if {{@Inject}} in combination with CDI could support self injection as well.
> With that projects migrating from {{@EJB}} to {{@Inject}} can do so more easily and the capability can be convenient for new projects as well (e.g. calling two separate {{@Transactional}} methods from a single method without being required to create a new bean).
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 10 months
[JBoss JIRA] (CDI-527) allow proxying of classes with non-private final methods
by Romain Manni-Bucau (JIRA)
[ https://issues.jboss.org/browse/CDI-527?page=com.atlassian.jira.plugin.sy... ]
Romain Manni-Bucau commented on CDI-527:
----------------------------------------
[~mkouba] annotation => spi so we can write an extension solving issues for legacy apps so this is fine IMO. Big advantage is to allow a *portable* solution which is reliable on the long term (opposed to impl solutions)
> allow proxying of classes with non-private final methods
> --------------------------------------------------------
>
> Key: CDI-527
> URL: https://issues.jboss.org/browse/CDI-527
> Project: CDI Specification Issues
> Issue Type: Feature Request
> Components: Beans
> Affects Versions: 1.2.Final
> Reporter: Mark Struberg
> Assignee: Mark Struberg
> Fix For: 2.0 (proposed)
>
>
> Currently we explicitly disallow proxying of classes with non-private final methods.
> EJB _does_ allow this. And there are a few final methods in the JDK and other libs. E.g. HashMap#initHashSeedAsNeeded. Currently we cannot have a producer method for it.
> We might rethink our decision and allow it. Probably with an own annotation like @AllowProxying which disables this check for certain cases (subclass managed-beans or producers).
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 10 months
[JBoss JIRA] (CDI-527) allow proxying of classes with non-private final methods
by Martin Kouba (JIRA)
[ https://issues.jboss.org/browse/CDI-527?page=com.atlassian.jira.plugin.sy... ]
Martin Kouba commented on CDI-527:
----------------------------------
Correct me if I'm wrong, but if the only way of using this "feature" would be declaring an annotation than we *will not be able to help legacy apps* (compiled against older CDI API, no source available, etc.) - this was one of the requirements often cited in previous comments. Also it might be problematic *to integrate a class we're not able to modify*. Just for completeness - I'm ok with this as both impls provide a non-portable solution already.
> allow proxying of classes with non-private final methods
> --------------------------------------------------------
>
> Key: CDI-527
> URL: https://issues.jboss.org/browse/CDI-527
> Project: CDI Specification Issues
> Issue Type: Feature Request
> Components: Beans
> Affects Versions: 1.2.Final
> Reporter: Mark Struberg
> Assignee: Mark Struberg
> Fix For: 2.0 (proposed)
>
>
> Currently we explicitly disallow proxying of classes with non-private final methods.
> EJB _does_ allow this. And there are a few final methods in the JDK and other libs. E.g. HashMap#initHashSeedAsNeeded. Currently we cannot have a producer method for it.
> We might rethink our decision and allow it. Probably with an own annotation like @AllowProxying which disables this check for certain cases (subclass managed-beans or producers).
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 10 months