Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API to obtain current injection point from Bean#create #637

Open
arjantijms opened this issue Nov 15, 2022 · 3 comments
Open

Add API to obtain current injection point from Bean#create #637

arjantijms opened this issue Nov 15, 2022 · 3 comments

Comments

@arjantijms
Copy link

As per the existing issue https://issues.redhat.com/browse/CDI-610

There's currently not a clear way on how to obtain the current injection point (if any) from Bean<T>#create.
A previously somewhat accepted way (though not specified) was:

  Bean<? extends Object> bean = beanManager.resolve(beanManager.getBeans(InjectionPoint.class));
  InjectionPoint injectionPoint = (InjectionPoint) beanManager.getReference(bean, InjectionPoint.class, creationalContext);

This however broke in some version of Weld.

Since getting the injection point is an often used feature in producers, I'd like to propose to introduce an easy API for this, so Bean<T> implementations can use this just as easily. E.g. something like: BeanManager#getCurrentInjectionPoint().

Also see: http://cdi-development-mailing-list.1064426.n5.nabble.com/Getting-injection-point-from-Bean-create-td5710505i20.html

@arjantijms
Copy link
Author

p.s. a workaround is now:

@Dependent
public class InjectionPointGenerator {

    // TODO: this is a workaround originally for older OWB versions, but while OWB is fixed, newer Weld
    // versions are now broken. It seems this needs to be fixed in CDI 2.1, or perhaps CDI 3.
    // See https://issues.jboss.org/browse/CDI-610

    @Inject
    private InjectionPoint injectionPoint;

    public InjectionPoint getInjectionPoint() {
        return injectionPoint;
    }

}
    public static InjectionPoint getCurrentInjectionPoint(BeanManager beanManager, CreationalContext<?> creationalContext) {
        Bean<InjectionPointGenerator> bean = resolve(beanManager, InjectionPointGenerator.class);

        return bean != null
                ? (InjectionPoint) beanManager.getInjectableReference(bean.getInjectionPoints().iterator().next(), creationalContext)
                : null;
    }

    @SuppressWarnings("unchecked")
    public static <T> Bean<T> resolve(BeanManager beanManager, Class<T> beanClass, Annotation... qualifiers) {
        Set<Bean<?>> beans = beanManager.getBeans(beanClass, qualifiers);

        for (Bean<?> bean : beans) {
            if (bean.getBeanClass() == beanClass) {
                return (Bean<T>) beanManager.resolve(Collections.<Bean<?>>singleton(bean));
            }
        }

        Bean<T> bean = (Bean<T>) beanManager.resolve(beans);

        if (bean == null && beanClass.getSuperclass() != Object.class) {
            return (Bean<T>) resolve(beanManager, beanClass.getSuperclass(), qualifiers);
        } else {
            return bean;
        }
    }

@Ladicek
Copy link
Contributor

Ladicek commented Nov 15, 2022

I agree with @mkouba's comments in the original issue -- the existing CDI API for programmatically looking up InjectionPoint is sufficient. The spec should clarify that this is possible, but only if the "currently injected" bean is @Dependent (which is probably gonna be interesting to put into text :-) ).

This however broke in some version of Weld.

I'd say that's probably a bug, but I'll let @manovotn comment on that :-)

@manovotn
Copy link
Contributor

manovotn commented Nov 15, 2022

This however broke in some version of Weld.

I'd say that's probably a bug, but I'll let @manovotn comment on that :-)

That sounds like a bug and I am not aware of any issue tracking that.
The linked CDI issue even shows Weld tests (here and here) that assert this very thing.
@arjantijms could you create a WELD issue with a test reproducing it for the case where this doesn't work?
I'd be happy to look into it but I need to know what is the scenario where this fails.

As for this issue, I am also of the opinion that you should be able to use programmatic lookup to obtain InjectionPoint.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants