For some reason, the following code is not working, and I do not understand why. My current, and quite hand-wavy, belief from fussing around with several slight variations is that because the bean is being created before there is an ExternalContext
its causing the exception. However, the ExternalContext
should exist at this point, or so I believe.
I have a few ideas for work arounds, such as a MessageProvider class instantiated in LoginBean and sent to the MessagesBean for later use, but I would much prefer to have a session bean as close to the format below instead of having it act as a wrapper. An explanation of why this fails, as well as a correction if possible would be greatly appreciated.
Below is the two classes that are of main concern:
@Named( value = "loginBean")
@RequestScoped
public class LoginBean {
private static final Logger LOG = Logger.getLogger(LoginBean.class.getName());
@Inject
private MessagesBean messagesBean;
@Inject
private LoginFormBean loginFormBean;
@Inject
private PersonBean personBean;
@Inject
private PersonFacade personFacade;
@NotNull
private String username;
@NotNull
private String password;
public LoginBean() {
}
/**
* Get the value of username
*
* @return the value of username
*/
public String getUsername() {
return username;
}
/**
* Set the value of username
*
* @param username new value of username
*/
public void setUsername(String username) {
this.username = username;
}
/**
* Get the value of password
*
* @return the value of password
*/
public String getPassword() {
return password;
}
/**
* Set the value of password
*
* @param password new value of password
*/
public void setPassword(String password) {
this.password = password;
}
public String login() {
Person person = personFacade.find(username);
if(person != null && person.getPasswordHash().equals(password)) {
personBean.setPerson(person);
return "success";
}
else {
messagesBean.setMessage(
loginFormBean.getUsernameInput().getClientId(),
"login.failed");
return "failure";
}
}
public String logout() {
return null;
}
}
@Named(value = "messagesBean")
@SessionScoped
public class MessagesBean implements Serializable {
private static final long serialVersionUID = 1L;
private FacesContext facesContext;
private Locale locale;
private ResourceBundle messageBundle;
/**
* Creates a new instance of MessagesBean
*/
public MessagesBean() {
}
@PostConstruct
private void init()
{
facesContext = FacesContext.getCurrentInstance();
locale = facesContext.getExternalContext().getRequestLocale();
messageBundle =
ResourceBundle.getBundle(
facesContext.getApplication().getMessageBundle(),
locale);
}
public void setMessage(String clientId, String messageKey)
{
FacesMessage facesMessage =
new FacesMessage(messageBundle.getString(messageKey));
facesContext.addMessage(clientId, facesMessage);
}
}
Below is a stack trace of the error that occurs with the above classes:
javax.faces.el.EvaluationException: org.jboss.weld.exceptions.WeldException: WELD-000049: Unable to invoke private void com.healthdataviews.healthdataviewstrial.support.MessagesBean.init() on com.healthdataviews.healthdataviewstrial.support.MessagesBean@1126aa67
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.jboss.weld.exceptions.WeldException: WELD-000049: Unable to invoke private void com.healthdataviews.healthdataviewstrial.support.MessagesBean.init() on com.healthdataviews.healthdataviewstrial.support.MessagesBean@1126aa67
at org.jboss.weld.injection.producer.DefaultLifecycleCallbackInvoker.invokeMethods(DefaultLifecycleCallbackInvoker.java:100)
at org.jboss.weld.injection.producer.DefaultLifecycleCallbackInvoker.postConstruct(DefaultLifecycleCallbackInvoker.java:81)
at org.jboss.weld.injection.producer.BasicInjectionTarget.postConstruct(BasicInjectionTarget.java:126)
at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:162)
at org.jboss.weld.util.bean.IsolatedForwardingBean.create(IsolatedForwardingBean.java:45)
at org.jboss.weld.context.AbstractContext.get(AbstractContext.java:96)
at org.jboss.weld.context.PassivatingContextWrapper$AbstractPassivatingContextWrapper.get(PassivatingContextWrapper.java:76)
at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.get(ContextualInstanceStrategy.java:101)
at org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.get(ContextualInstanceStrategy.java:178)
at org.jboss.weld.bean.ContextualInstance.get(ContextualInstance.java:50)
at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:99)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:125)
at com.healthdataviews.healthdataviewstrial.support.MessagesBean$Proxy$_$$_WeldClientProxy.setMessage(Unknown Source)
at com.healthdataviews.healthdataviewstrial.controller.ejb.LoginBean.login(LoginBean.java:100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.el.parser.AstValue.invoke(AstValue.java:289)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
... 36 more
I discovered exactly where the error was occurring. When I call getMessageBundle
, I am getting a NullPointerException
which is causing ResourceBundle.getBundle()
to search for a null bundle which is causing it to crash on @PostConstruct init()
. New question: How do I link my Messages.properties to the getMessageBundle()
call, or should I just translate it to getResourceBundle("bundle")
?
I got it working by setting the <message-bundle>
in my faces-config.xml. Is there any way to include it without loading in each .xhtml file other than declaring it a <resource-bundle>
as well?
Kindly check not equal to null Statement for messageBundle in @Postconstruct
Method.
i.e.,
if(messageBundle != null)
messageBundle = ResourceBundle.getBundle(
facesContext.getApplication().getMessageBundle(),
locale);