5

I have a Facelet that has two <h:forms>. The command link in one form executes without a problem. The command link in the other form does not work: a NullPointerException is thrown because FacesContext.getCurrentInstance() is returning null. It appears to me that the request goes through FacesServlet so it doesn't make sense that FacesContext.getCurrentInstance() would return null.

Here's the XHTML:

<h:form>
    <h:commandLink action="#{localeManager.setLanguage('en')}">English</h:commandLink>
</h:form>

The resulting HTML is here:

<form id="j_idt20" name="j_idt20" method="post" action="/Patrac/faces/academicyear.xhtml" enctype="application/x-www-form-urlencoded">
    <input type="hidden" name="j_idt20" value="j_idt20" />
    <script type="text/javascript" src="/Patrac/faces/javax.faces.resource/jsf.js?ln=javax.faces&amp;stage=Development"></script>
    <a href="#" onclick="mojarra.jsfcljs(document.getElementById('j_idt20'),{'j_idt20:j_idt22':'j_idt20:j_idt22'},'');return false">English</a>
    <input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="-3103232499387158697:-8681635922139458233" autocomplete="off" />
</form>

Here is the LocaleManager:

@Named
@SessionScoped
public class LocaleManager implements Serializable
{
...
    public void setLanguage(String language)
    {
        this.locale = new Locale(language);
        FacesContext fc = FacesContext.getCurrentInstance();


        UIViewRoot uivr = fc.getViewRoot(); <===== NullPointerException

        uivr.setLocale(locale);
    }
}

And here's the stack trace:

16:35:31,697 WARNING [javax.enterprise.resource.webcontainer.jsf.lifecycle] (http--127.0.0.1-8443-4) #{localeManager.setLanguage('en')}: java.lang.NullPointerException: javax.faces.FacesException: #{localeManager.setLanguage('en')}: java.lang.NullPointerException
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
    at javax.faces.component.UICommand.broadcast(UICommand.java:315) [jboss-jsf-api_2.1_spec-2.0.0.Beta1.jar:2.0.0.Beta1]
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) [jboss-jsf-api_2.1_spec-2.0.0.Beta1.jar:2.0.0.Beta1]
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) [jboss-jsf-api_2.1_spec-2.0.0.Beta1.jar:2.0.0.Beta1]
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) [jboss-jsf-api_2.1_spec-2.0.0.Beta1.jar:2.0.0.Beta1]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.7.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.7.Final.jar:]
    at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) [weld-core-1.1.4.Final.jar:2011-11-22 20:01]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.7.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.7.Final.jar:]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.7.Final.jar:]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.7.Final.jar:]
    at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.0.CR1b.jar:7.1.0.CR1b]
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:151) [jboss-as-web-7.1.0.CR1b.jar:7.1.0.CR1b]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.7.Final.jar:]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.7.Final.jar:]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.7.Final.jar:]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362) [jbossweb-7.0.7.Final.jar:]
    at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:897) [jbossweb-7.0.7.Final.jar:]
    at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:626) [jbossweb-7.0.7.Final.jar:]
    at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:2033) [jbossweb-7.0.7.Final.jar:]
    at java.lang.Thread.run(Thread.java:722) [:1.7.0_02]
Caused by: javax.faces.el.EvaluationException: java.lang.NullPointerException
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102) [jboss-jsf-api_2.1_spec-2.0.0.Beta1.jar:2.0.0.Beta1]
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
    ... 24 more
Caused by: java.lang.NullPointerException
    at com.patrac.controller.LocaleManager.setLanguage(LocaleManager.java:38) [Patrac-ejb-1.0-SNAPSHOT.jar:]
    at com.patrac.controller.LocaleManager$Proxy$_$$_WeldClientProxy.setLanguage(LocaleManager$Proxy$_$$_WeldClientProxy.java) [Patrac-ejb-1.0-SNAPSHOT.jar:]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.7.0_02]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [:1.7.0_02]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [:1.7.0_02]
    at java.lang.reflect.Method.invoke(Method.java:601) [:1.7.0_02]
    at org.apache.el.parser.AstValue.invoke(AstValue.java:262) [jbossweb-7.0.7.Final.jar:]
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278) [jbossweb-7.0.7.Final.jar:]
    at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:39) [weld-core-1.1.4.Final.jar:2011-11-22 20:01]
    at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50) [weld-core-1.1.4.Final.jar:2011-11-22 20:01]
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) [jboss-jsf-api_2.1_spec-2.0.0.Beta1.jar:2.0.0.Beta1]
    ... 25 more

Taking a look at this answer to a similar question my first thought was that the request was not going through FacesServlet. But looking at form action field in the generated HTML and the stack trace, above, it looks to me like the request is going through FacesServlet.

Any ideas on this? What am I not getting?

Community
  • 1
  • 1
Patrick Garner
  • 3,201
  • 6
  • 39
  • 58
  • How exactly is the sort link related to this? – BalusC Feb 03 '12 at 22:48
  • @BalusC I've cut out the stuff about the link that works correctly (the sort link) to make the question easier to read. – Patrick Garner Feb 04 '12 at 00:28
  • Well, I wondered if the other link *also* called `FacesContext#getCurrentInstance()` and if it worked as expected. I still do wonder this. After all, I think that this is a bug in the JBoss server used. In the stacktrace I see mixed JSF API/impl versions, this is not right. Try deploying on a different make/version server, for example JBoss 6.1.0 or Glassfish 3.1.2. – BalusC Feb 04 '12 at 14:05
  • @BalusC, no, the other link did not call `FacesContext#getCurrentInstance()`. After reading your [Communication in JSF](http://balusc.blogspot.com/2006/06/communication-in-jsf.html), I think the problem was that I was trying to pass a parameter to the backing bean like this: `localeManager.setLanguage('en')`, when I should have been using `` in concert with an ActionListener or ``. Thoughts on this? – Patrick Garner Feb 04 '12 at 17:48
  • 1
    No, you're using EL 2.2 which is perfectly fine. That article is targeted on JSF 1.2 and Java EE 5. Try calling `FacesContext#getCurrentInstance()` on other action methods as well, just to exclude the one and other. If you encounter the same issue in other action methods (i.e. it returns `null`) then there's something wrong at higher level than in the code posted so far. – BalusC Feb 04 '12 at 18:10
  • 1
    @BalusC I finally came to the realization that it works fine when deployed as a WAR, but when I deploy as an EAR it does not work. I took the application, which was structured to be deployed as an EAR and reorganized the same exact files so that it could be deployed as a WAR and it deployed and ran without errors. So I opened a new question, [JBoss AS 7 error: WAR deployment succeeds, EAR deployment fails](http://stackoverflow.com/questions/9154174/jboss-as-7-error-war-deployment-succeeds-ear-deployment-fails). – Patrick Garner Feb 05 '12 at 23:51

2 Answers2

1

The problem was that I was invoking FacesContext.getCurrentInstance() from the EJB tier. This is why it worked when deployed as a WAR, but not as an EAR. I was very low on the Java EE learning curve at the time :-)

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
Patrick Garner
  • 3,201
  • 6
  • 39
  • 58
-1

The @SessionScoped annotation is it imported from javax.faces.bean package or javax.enterprise.context? You should never use the javax.faces.bean package annotations since it will give you a different container other than CDI, and only stick to javax.enterprise.context.

Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
bogdan.mustiata
  • 1,725
  • 17
  • 26
  • 1
    While your statement is true, this would surely not have resulted in this behavior and exception. So your answer is invalid. Read the comments on the question for the answer which OP found himself (but didn't post as a normal answer). – BalusC Apr 03 '12 at 11:15
  • It's true what you're saying, and I believe the very likely root cause of it is having classloader issues since ear deployments create a distinct classloader for the war. So I assume he has somehow bundled the JSF in the ear deployment as well, and thus calls it from a different classloader than the war that is embedded. On the other hand since the question is not resolved I just gave another guess, since "In the stacktrace I see mixed JSF API/impl versions, this is not right. " also can not cause the NPE he's talking about. – bogdan.mustiata Apr 03 '12 at 11:50