How to create an injectable Resourcebundle with Weld
ifischer Jun 8, 2010 2:06 PMIn my Java EE 6 application, i'm often dealing with the ResourceBundle in my Beans to get localized messages. To get the correct ResourceBundle, i always have to obtain it in this way:
FacesContext facesContext = FacesContext.getCurrentInstance();
String sessionErrorString = ResourceBundle.getBundle("/messages",
facesContext.getViewRoot().getLocale()).getString("sessionTimeOut")
So i always have to obtain the instance of FacesContext and resolve the locale.
As this is not very elegant, i looked into the Seam 3 Source and found some nice producer classes, i.e. for the Locale and for the FacesContext.
Now i want to use them to create a ResourceBundle-Producer, so i can shorten the above code by injection to the following:
@Inject ResourceBundle bundle;
(...)
public void test() {
log.info(bundle.getString("myMessage"));
}
So these are the classes i obtained from the current Seam 3-trunk. I need them for my BundleResolver:
FacesLocaleResolver:
public class FacesLocaleResolver {
@Inject
FacesContext facesContext;
public boolean isActive() {
return (facesContext != null) && (facesContext.getCurrentPhaseId() != null);
}
@Produces @Faces
public Locale getLocale() {
if (facesContext.getViewRoot() != null)
return facesContext.getViewRoot().getLocale();
else
return facesContext.getApplication().getViewHandler().calculateLocale(facesContext);
}
}
FacesContextProducer:
public class FacesContextProducer {
@Produces @RequestScoped
public FacesContext getFacesContext() {
FacesContext ctx = FacesContext.getCurrentInstance();
if (ctx == null)
throw new ContextNotActiveException("FacesContext is not active");
return ctx;
}
}
And this shall be my ResourceBundle-Resolver:
public class ResourceBundleProducer {
@Inject
public Locale locale;
@Inject
public FacesContext facesContext;
@Produces
public ResourceBundle getResourceBundle() {
ResourceBundle.getBundle("/messages", facesContext.getViewRoot().getLocale() )
}
}
Unfortunately, my BundleResolver doesn't work, as ResourceBundle is not Serializable. I'm getting the following Error from Weld when trying to access a JSF-page which calls a bean that uses my ResourceBundle:
Caused by: org.jboss.weld.IllegalProductException: WELD-000054 Producers cannot produce non-serializable instances for injection into non-transient fields of passivating beans\\n\\nProducer\: org.jboss.weld.bean-/D:/Program Files (x86)/GlassFish-Tools-Bundle-For-Eclipse-1.2/glassfishv3/glassfish/domains/teachernews/applications/teachernews/-ProducerMethod-services.producers.ResourceBundleProducer.getResourceBundle()\\nInjection Point\: field web.PersonHome.bundle
Are there any ways to get my ResourceBundleResolver to work? Can i somehow wrap ResourceBundle and make it serializable? Or are there any other mechanisms to get a similar functionality?
Thanks in advance!