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!