Reputation: 740
This is in relation to the workaround for the known issue of JSF FacesConverter not being an eligible @Inject target for CDI. I followed the workaround at CDI Injection into a FacesConverter. However, in my FacesConverter, I had been utilizing the feature of having the Class of the object passed into a constructor.
From the javadoc - "If a converter has a single argument constructor that takes a Class instance and the Class of the data to be converted is known at converter instantiation time, this constructor must be used to instantiate the converter instead of the zero-argument version." This is in direct conflict with the CDI requirement for "normal scope" beans where a no-arg or @Inject annotated constructor is all that's allowed.
So in summary, I want to use a Converter that can take CDI Injections, and has access to the Class of the object being converted at runtime.
I am using Mojarra 2.2.4 on Glassfish 4 with Weld 2.0.4.
Upvotes: 1
Views: 1032
Reputation: 740
For those who might be interested in this alternative, I was able to replace the Inject annotations with programmatic lookup via BeanManager in the constructor. The condensed code is below. I've not performance tested, and suspect that may be a downside. If time permits I'll compare to the Omnifaces solution.
EDIT: The cost of the BeanManager lookup turned out to be minimal. The constructor takes on average <1ms.
@FacesConverter(forClass = AbstractEntity.class)
public class EntityConverter implements Converter {
private LocationService locationService;
private Class entityClass;
//Special parameterized constructor for @FacesConverter described in the original question
public EntityConverter(Class entityClass) throws NamingException {
this.entityClass = entityClass;
this.locationService = loadManagedBean(LocationService.class, "locationService");
}
//Generic lookup method for @Named managed beans
protected <T> T loadManagedBean(Class<T> clazz, String beanName) throws NamingException {
InitialContext initialContext = new InitialContext();
BeanManager bm = (BeanManager) initialContext.lookup("java:comp/BeanManager");
Bean<T> bean = (Bean<T>) bm.getBeans(beanName).iterator().next();
CreationalContext<T> cc = bm.createCreationalContext(bean);
T beanInstance = (T) bm.getReference(bean, clazz, cc);
return beanInstance;
}
}
Upvotes: 3