Beans.getReference(...) fails with CDI producer class #337

Closed
flofis opened this Issue Jan 5, 2017 · 1 comment

Projects

None yet

2 participants

@flofis
flofis commented Jan 5, 2017 edited

Hi,
since the BeanManager Enum has been deprecated since Omnifaces 2.5, we changed most of the
BeanManager.INSTANCE.getReference(...) calls to the recommended Beans.getReference(...) in our converters, etc.

However Beans.getReference seems to have different / broken behaviour wrt producer methods.
Consider SomeClass that is produced like this:

@Dependent
public class SomeClassProducer{
	@Produces
	@RequestScoped
	public SomeClass createSomeClass  () {
		return new SomeClass ();
	}
}

SomeClass someObjectA = BeanManager.INSTANCE.getReference(SomeClass .class);
Works fine and returns the CDI proxy object.

SomeClass someObjectA = Beans.getReference(SomeClass .class);
However fails with the following error:

org.jboss.weld.exceptions.IllegalArgumentException: WELD-001305: The given type class SomeClassProducer is not a type of the bean Producer Method [SomeClass] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces @RequestScoped public SomeClassProducer.createSomeClass ()]
at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:762)
at org.omnifaces.util.BeansLocal.getReference(BeansLocal.java:94)
at org.omnifaces.util.BeansLocal.getReference(BeansLocal.java:85)
at org.omnifaces.util.Beans.getReference(Beans.java:114)

The cause of this problem is the following Code in BeansLocal:

public static <T> T getReference(BeanManager beanManager, Bean<T> bean) {
		return (T) beanManager.getReference(bean, **bean.getBeanClass()**, beanManager.createCreationalContext(bean));
}

As documented getBeanClass returns the "managed bean or session bean or of the bean that declares the producer method or field."

Is this intended? Passing the intended class instead of bean.getBeanClass() would yield the desired result.
This is also what the old BeanManager implementation did:
Class beanClass =>
Object reference = getReference.invoke(beanManager, bean, beanClass, creationalContext);

We are using Websphere Liberty (WebSphere Application Server 16.0.0.4) using Weld 2.4.
Is this change in behaviour intended or just a bug?

Cheers,
Florian

@BalusC BalusC closed this in c996912 Jan 7, 2017
@BalusC
Member
BalusC commented Jan 7, 2017 edited

Thank you for your report. This is certainly not the intent. The fix is available as per today's 2.6-SNAPSHOT. Can you please give it a try and let me know?

The more clean way, however, is to directly use CDI's own utility class.

SomeClass someObjectA = CDI.current().select(SomeClass.class);

This only doesn't work in very specific circumstances and this is where only Beans#getReference() would work. One such case which I ever encountered is during the close of a JSR356 websocket in Undertow/WildFly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment