I'm developing an app using Primefaces tag library.
So far I've copied some examples from their official website and all seems to work except for anything that uses the RequestContext.getCurrentInstance() method. It either returns null every time, causing Tomcat to throw a NullPointer exception or hangs forever, never returning anything.
Here's my code (the case where it hangs):
GlobalCounterBean.java
package org.primefaces.examples.view;
import java.io.Serializable;
import org.primefaces.context.RequestContext;
public class GlobalCounterBean implements Serializable{
private int count;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public synchronized void increment() {
count++;
System.out.println("aaaa");
RequestContext.getCurrentInstance().push("counter", count);
}
}
test.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<p:spinner />
<h:form>
<h:outputText value="#{globalCounter.count}" styleClass="ui-widget display" />
<br />
<p:commandButton value="Click" actionListener="#{globalCounter.increment}" />
</h:form>
<p:push onmessage="handleMessage" channel="counter" />
<script type="text/javascript">
function handleMessage(evt, data) {
$('.display').html(data);
}
</script>
</h:body>
</html>
And here's the code for the case when it returns null (all files are in the same project):
ChatController.java:
package org.primefaces.examples.view;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.primefaces.context.RequestContext;
public class ChatController implements Serializable {
private final static String CHANNEL = "chat";
private String message;
private String username;
private boolean loggedIn;
private Set<String> users = new HashSet<String>();
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public boolean isLoggedIn() {
return loggedIn;
}
public void setLoggedIn(boolean loggedIn) {
this.loggedIn = loggedIn;
}
public void send() {
RequestContext.getCurrentInstance().push(CHANNEL, username + ": "+ message);
message = null;
}
public void login() {
RequestContext requestContext = RequestContext.getCurrentInstance();
if(users.contains(username)) {
loggedIn = false;
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Username taken", "Try with another username."));
requestContext.addPartialUpdateTarget("growl");
}
else {
users.add(username);
loggedIn = true;
requestContext.push(CHANNEL, username + " joined the channel.");
}
}
public void disconnect() {
RequestContext.getCurrentInstance().push(CHANNEL, username + " has left the channel.");
loggedIn = false;
username = null;
}
}
chat.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Insert title here</title>
</head>
<body>
<f:view>
<p:growl id="growl" showDetail="true" />
<h:form>
<p:fieldset id="container" legend="PrimeChat">
<h:panelGroup rendered="#{chatController.loggedIn}" >
<p:outputPanel layout="block" style="width:600px;height:200px;overflow:auto"
styleClass="chatroom" />
<p:spinner />
<p:separator />
<p:inputText value="#{chatController.message}" styleClass="messageInput" />
<p:spacer width="5" />
<p:commandButton value="Send" actionListener="#{chatController.send}" global="false" oncomplete="$('.messageInput').val('').focus()"/>
<p:spacer width="5" />
<p:commandButton value="Disconnect" actionListener="#{chatController.disconnect}" global="false"
oncomplete="chatAgent.close()" update="container" />
</h:panelGroup>
<h:panelGroup rendered="#{not chatController.loggedIn}" >
Username: <p:inputText value="#{chatController.username}" />
<p:spacer width="5" />
<p:commandButton value="Login" actionListener="#{chatController.login}" update="container"
icon="ui-icon-person"/>
</h:panelGroup>
</p:fieldset>
</h:form>
<p:push onmessage="handleMessage" channel="chat" widgetVar="chatAgent" />
<script type="text/javascript">
function handleMessage(evt, data) {
var chatContent = $('.chatContent');
chatContent.append(data + '<br />');
//keep scroll
chatContent.scrollTop(chatContent.height());
}
</script>
<script type="text/javascript">
function handleComplete(xhr, status, args) {
if(args.validationFailed) {
PrimeFaces.debug("Validation Failed");
}
else {
PrimeFaces.debug("Save:" + args.saved);
PrimeFaces.debug("FirstName: " + args.user.firstname + ", Lastname: " + args.user.lastname);
}
}
</script>
</f:view>
</body>
</html>
faces-config.xml:
<?xml version="1.0" encoding="utf-8"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<managed-bean eager="true">
<managed-bean-name>chatController</managed-bean-name>
<managed-bean-class>org.primefaces.examples.view.ChatController</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>globalCounter</managed-bean-name>
<managed-bean-class>org.primefaces.examples.view.GlobalCounterBean</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
<!--
No ManagedBean declarations here as we are using @ManagedBean Annotations.
-->
</faces-config>
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" >
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
And here's the exception thrown in tomcat console:
2012-05-27 19:16:25 com.sun.faces.context.ExceptionHandlerImpl log
SEVERE: JSF1073: javax.faces.event.AbortProcessingException caught during processing of INVOKE_APPLICATION 5 : UIComponent-ClientId=j_idt2:j_idt16, Message=java.lang.NullPointerException
2012-05-27 19:16:25 com.sun.faces.context.ExceptionHandlerImpl log
SEVERE: java.lang.NullPointerException
javax.faces.event.AbortProcessingException: java.lang.NullPointerException
at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:178)
at javax.faces.event.ActionEvent.processListener(ActionEvent.java:84)
at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:773)
at javax.faces.component.UICommand.broadcast(UICommand.java:296)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:781)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1246)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:77)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:680)
Caused by: java.lang.NullPointerException
at org.primefaces.examples.view.ChatController.login(ChatController.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.el.parser.AstValue.invoke(AstValue.java:191)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:149)
... 21 more
Your
web.xml
is missing the "URL Configuration" part of PrimeFaces Push setup.As mentioned in my answer on your previous question, Installation details of PrimeFaces Push are outlined in chapter 6 of PrimeFaces User's Guide. Here's an extract of relevance for the step you're missing: