5

I managed to get a prototype with JSF2 get working at Googles AppEngine following this tutorial. Now I have some odd behavior with a ViewScoped ManagedBean:

@ManagedBean @ViewScoped
public class TestBean implements Serializable
{
  private String text;         //getter/setter
  private List<String> texts;    //getter

  @PostConstruct public void init() 
  {
    texts = new ArrayList<String>();
    texts.add("Test");
    text = new String();
  }

  public void save(ActionEvent ae)
  {  
    texts.add(text);
    text = new String();
  }
}

This is my .xhtml page:

<h:body id="body">
  <f:view contentType="text/html">
     <h:form id="frm">
        <p:panel>  
            <h:panelGrid columns="2" id="grid">   
                <p:inputText value="#{testBean.text}"/>  
                <p:commandButton value="Add" update=":frm:op @parent"
                                actionListener="#{testBean.save}" />   
            </h:panelGrid>
        </p:panel>
        <p:outputPanel id="op">
           <p:dataTable var="v" value="#{testBean.texts}">  
              <p:column><h:outputText value="#{v}" /></p:column>
           </p:dataTable>
        </p:outputPanel>
     </h:form>
  </f:view>
</h:body>

This works fine with a local deployment (Using the Eclipse tools for GAE), but if I deploy this to GAE, nothing happens if I click on the Add-Button. Additional Tests with the scope (at GAE) show the following after clicking on Add:

  • @RequestScoped: Entered Text does not disappear, not added to dataTable
  • @ViewScoped: Entered Text does not disappear, not added to dataTable
  • @SessionScoped: Entered Text disappear, dataTable always has two entries: "Test" and the last entered Text

I have the same setting from the tutorial

<context-param>  //web.xml
  <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
  <param-value>server</param-value>
</context-param>

//appengine-web.xml
<sessions-enabled>true</sessions-enabled>

Update 1

Here are the results of additional tests with @ManagedBean @ViewScoped annotation:

During the first request (or manual refreh of the page), the @PostConstruct init() method is called. If I click on the button nothing happes, the request to test.jsf is logged in app engines log, but there is no log in my save() method. Firebug shows me a POST request to test.jsf and the following answer:

<?xml version='1.0' encoding='UTF-8'?>
<partial-response><error>
  <error-name>class javax.faces.application.ViewExpiredException</error-name>
  <error-message>
     <![CDATA[viewId:/test.jsf - View /test.jsf could not be restored.]]>
  </error-message>
  </error>
  <extension primefacesCallbackParam="validationFailed">
    {"validationFailed":false}
  </extension>
</partial-response>

Update 2

I have used mojarra-2.0.4 but now updated to 2.0.6. The same issue, but a new observation: If I clear all Firefox caches, the ViewExpiredException did not appear, but I'm only able to add 1 Element to the List<String>. The @PostConstruct is only invoked once and not for each click on the button.

Then I tried myfaces-2.0.7, but got this exception:

Uncaught exception from servlet
java.lang.NoClassDefFoundError: Could not initialize class
com.google.apphosting.runtime.security.shared.stub.javax.naming.InitialContext

I'm not sure if I should try to get myfaces working since google explicitly mentions mojarra (2.0.4) in their tutorial.

References

Thor
  • 6,607
  • 13
  • 62
  • 96
  • Can you please elaborate "nothing happens" more in developer's perspective instead of from enduser's perspective? What does a HTTP traffic debugger like Firebug say? Does the ajax POST request get sent? What response exactly is returned? Does the bean's action method get invoked? Does the setter get invoked? Isn't the bean unnecessarily (post)constructed upon every request from the same view? Etc. Turn on the debugger or do poor man's debugging by throwing in a bunch of `System.out.println()` lines at strategic locations printing info and/or variables of interest. – BalusC Aug 27 '11 at 18:18
  • Dear BalusC, you are absolutely right. I will add debugging information. Thanks for pointing this out (and remembering me for Firebug)! – Thor Aug 28 '11 at 15:49
  • Ha, you got a `ViewExpiredException`. Now that boils pretty good down. Next question, are you using MyFaces or Mojarra? What version? I recall have seen this kind of problem before on a certain version of MyFaces on GAE. Regardless, try upgrading JSF impl/version to the latest supported by GAE. [Mojarra](http://javaserverfaces.java.net/) is currently at 2.0.6 for Servlet 2.5 containers, or 2.1.2 for Servlet 3.0 containers (I don't do GAE, but I imagine that it still supports max Servlet 2.5). [MyFaces](http://myfaces.apache.org/download.html) is at 2.0.7 and 2.1.1 respectively. – BalusC Aug 28 '11 at 16:40
  • I found a similar SO question: http://stackoverflow.com/questions/4813946/viewexpiredexception – BalusC Aug 28 '11 at 16:42

1 Answers1

3

Normally I don't answer my questions and I only rate this answer as a workaround and not as the correct answer. Event if I don't like client state saving, this seems to fix the odd behavior. But I have to check this in detail:

<context-param>
  <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
  <param-value>client</param-value>
</context-param>

Perhaps we should wait until JAVASERVERFACES-1886 is resolved.

Thor
  • 6,607
  • 13
  • 62
  • 96