0

Used this StackOverflow answer to try an implement a submitless form. The page consists of a selectomenu control and a table. On change of the selection I wish to refresh the table body. The page loads without issues, but when the selection is made I get the following error occurs:

10:22:48,241 ERROR [[FacesServlet]] Servlet.service() for servlet FacesServlet threw exception: java.lang.NullPointerException
    at com.sun.faces.context.PartialViewContextImpl.createPartialResponseWriter(PartialViewContextImpl.java:441) [jsf-impl-2.1.7-jbossorg-2.jar:]
    at com.sun.faces.context.PartialViewContextImpl.access$300(PartialViewContextImpl.java:71) [jsf-impl-2.1.7-jbossorg-2.jar:]
    at com.sun.faces.context.PartialViewContextImpl$DelayedInitPartialResponseWriter.getWrapped(PartialViewContextImpl.java:582) [jsf-impl-2.1.7-jbossorg-2.jar:]
    at javax.faces.context.PartialResponseWriter.startDocument(PartialResponseWriter.java:115) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
    at com.sun.faces.context.AjaxExceptionHandlerImpl.handlePartialResponseError(AjaxExceptionHandlerImpl.java:199) [jsf-impl-2.1.7-jbossorg-2.jar:]
    at com.sun.faces.context.AjaxExceptionHandlerImpl.handle(AjaxExceptionHandlerImpl.java:123) [jsf-impl-2.1.7-jbossorg-2.jar:]
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119) [jsf-impl-2.1.7-jbossorg-2.jar:]
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116) [jsf-impl-2.1.7-jbossorg-2.jar:]
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) [jsf-impl-2.1.7-jbossorg-2.jar:]
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]
    at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:505) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:445) [jbossweb-7.0.13.Final.jar:]
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
    at java.lang.Thread.run(Thread.java:636) [rt.jar:1.6.0_18]

I'm using JBoss-AS-7.1.1, and the selectonmenu looks like this:

<h:selectOneMenu id="ship"
             value="#{shipManager.current}">
    <f:selectItems value="#{shipManager.list}"
               var="ship"
               itemValue="#{ship}"
               itemLabel="#{ship.name}" />
    <f:ajax listener="#{shipManager.changeShip}" />
</h:selectOneMenu> 

If I remove the ajax component then no issues although (of course) the shipManager is not updated.

Once I have the selection made I would then like to add the renderer part to refresh my table body.

Many thanks for any help given.

Steve

As requested here is my XHTML code:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets">

  <h:head>
    <title>Voyage Cruises</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <link type="text/css" rel="stylesheet" media="all" href="/css/screen.css"/>
    <link type="text/css" rel="stylesheet" media="all" href="/css/cruise.css"/>
    <script src="http://open.mapquestapi.com/sdk/js/v7.0.s/mqa.toolkit.js"></script> 
    <script src="js/map.js" ></script>
    <script src="js/cruise.js" ></script>
  </h:head>

  <h:body>
    <div id="page">
      <div id="float-map">
    <div id="map"></div>
      </div>

      <h:form id="ship-form">

    <div id="ship-controls">
      <div class="float-ctrls">
        <a href="/ports.html" title="Find Ports"><img src="/images/action_search.png" alt="Find Ports"/></a>
      </div>
      <div>
        <span id="ship-selector" >
          <h:selectOneMenu id="ship"
                   value="#{shipManager.current}">
        <f:selectItems value="#{shipManager.list}"
                   var="ship"
                   itemValue="#{ship}"
                   itemLabel="#{ship.name}" />
        <f:ajax execute="ship" render="@form" listener="#{shipManager.changeShip}" />
          </h:selectOneMenu> 
        </span>
        <select id="month" />
        <select id="year" />
        <br />
        <span class="input-container"><b>Tonnage:</b><input id="tonnage" type="text" size="6" value="30,277" /></span>
        <span class="input-container"><b>Audit Time:</b><input id="audit" type="text" size="2" value="6" /></span>
        <span class="input-container"><b>Fleet:</b><input id="fleet" type="text" size="20" value="P&amp;O" /></span>
      </div>
    </div>

    <table class="cruise">
      <thead>
        <tr>
          <th class="date">Date</th>
          <th class="port">Port</th>
          <th class="arrive">Arrive</th>
          <th class="depart">Depart</th>
        </tr>
      </thead>
      <tbody>
        <ui:repeat var="cruise"
               value="#{cruiseManager.list}" 
               varStatus="table">
          <tr class="#{table.even ? 'even' : 'odd'}">
        <td class="date">
          <h:outputFormat value="{0, date,d MMM}">
            <f:param value="#{cruise.date}" />
          </h:outputFormat>
        </td>
        <h:panelGroup rendered="#{null != cruise.port}">
          <td class="port">#{cruise.port.name}</td>
          <td class="arrive">
            <h:outputFormat rendered="#{null != cruise.arrival}"
                    styleClass="#{cruise.arrivalEstimated ? 'est-time' : 'act-time'}"
                    value="{0, date,HH:mm}">
              <f:param value="#{cruise.arrival}" />
            </h:outputFormat>
          </td>
          <td class="depart">
            <h:outputFormat rendered="#{null != cruise.departure}"
                    styleClass="#{cruise.departureEstimated ? 'est-time' : 'act-time'}"
                    value="{0, date,HH:mm}">
              <f:param value="#{cruise.departure}" />
            </h:outputFormat>
          </td>
        </h:panelGroup>
        <h:panelGroup rendered="#{null == cruise.port}">
          <td class="at-sea" colspan="3">At Sea</td>
        </h:panelGroup>
          </tr>
        </ui:repeat>
      </tbody>
    </table>

      </h:form>
    </div>
  </h:body>
</html>

And the ShipManager:

package com.nutrastat.voyager.web;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.AjaxBehaviorEvent;

import com.nutrastat.voyager.db.HarbourMasterLocal;
import com.nutrastat.voyager.db.ShipEntity;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ManagedBean
@ViewScoped
public class ShipManager 
    implements Serializable {

    static final long serialVersionUID = -3017226836104715117L;

    private transient final Logger log;

    private ShipEntity currentShip;

    @EJB
    private HarbourMasterLocal harbourMaster;

    public ShipManager() {
    log = LoggerFactory.getLogger(getClass());
    }

    public ShipEntity getCurrent() {
    if (log.isInfoEnabled())
        log.info("getCurrent(): " + currentShip);
    return currentShip;
    }

    public void setCurrent(ShipEntity ship) {
    if (log.isInfoEnabled())
        log.info("setCurrent(" + currentShip + "): " + ship);
    currentShip = ship;
    }

    public void changeShip(AjaxBehaviorEvent evt) {
    if (log.isInfoEnabled())
        log.info("Ship now: " + currentShip);
    }

    public List<ShipEntity> getList() {
    try {
        return harbourMaster.listShips();

    } catch (Exception cause) {
        log.error("Getting the list of ships", cause);
        return new ArrayList<ShipEntity>(0);
    }
    }
}
Community
  • 1
  • 1
Dobbo
  • 1,188
  • 3
  • 16
  • 27

2 Answers2

3

Your stack trace looks incomplete in that it doesn't actually refer to your code(which is where I'd expect the npe be thrown). That notwithstanding, your select menu doesn't have a converter, so any other problems aside, your form would probably still not save or register the selection

  1. Implement a JSF converter and declare it on that selectonemenu. This is mandatory when a select type component needs to select and save complex POJO types You can look at this example

  2. Try to get rid of that gigantic <h:form/> in your markup. There are too many other components in that form that could be causing you problems. Break the components into smaller chunks in separate forms

kolossus
  • 20,559
  • 3
  • 52
  • 104
  • Hi. My stack trace may look incomplete but it is what it is. As I didn't need to store the POJO I converted the selectOneMenu to use just strings. That and removing the other select items that wheren't being used yet (but will be needed) cleared error and everything works just find now. Many thanks. – Dobbo Jan 03 '13 at 16:15
0

If the scope of your bean is @RequestScoped then change it to @ViewScoped , in general ajax better be done with @ViewScoped... cause new instance of the bean created upon each submit...

@ManagedBean(name="shipManager")
@ViewScoped

Also Make sure that the changeShip method takes AjaxBehaviorEvent as the parameter

(ie)

 public void changeShip (AjaxBehaviorEvent event){
//** do your stuf 
 }

and also specidy the execute and Render attributes inside f:Ajax

<f:ajax  execute="ship" render="@form"  listener="#{shipManager.changeShip}" />
Muthu Raman
  • 154
  • 2
  • 13
  • My changeShip() method did not have the AjaxBehaviourEvent parameter, but now does. The scope of the bean was SessionScoped, but both that and ViewScoped cause the error. – Dobbo Jan 03 '13 at 12:13
  • Did you also add the execute and Render attributes inside f:ajax as specified in the answer ? and if you are using ajax better use @ViewScoped itself .. – Muthu Raman Jan 03 '13 at 12:33
  • I did, but it still causes the exception. – Dobbo Jan 03 '13 at 12:47
  • Its difficult then to see whats wrong here ...Make sure you have the getters and setters methods for all the properties in your bean class . also try posting ur facelet .xhtml code .that might give an idea of what might have gone wrong – Muthu Raman Jan 03 '13 at 13:11
  • Hi Muthu, as requested I've posted the code for the XHTML and, just in case, the ShipManager. Your help is much appreciated. – Dobbo Jan 03 '13 at 13:50