Ok, it's kind of a trivial question, but here it goes. I want to show the progress of various inserts/updates made on a database, using a <h:inputTextArea value="bean.status" disabled="true"/> in my view (using richfaces). The Bean is a backing bean with a status attribute and a method to add status messages it:
public void addMessage(String message) {
status = status.concat(message + "\n");
}
There is a "migrate" button that starts the process. My problem is that the text area is update only at the end of the migrator method. What I need is that everytime the status is updated, the input text area gets updated too. So...
1 - How to do it?
2 - Is there a better way to implement this?
According to the RichFaces Component References it's needed:
Setup Push
Use a server-side or client-side approach
Implement a message producer
Handle push messages
So I did:
Install runtime dependencies (Atmosphere): -- Added atmosphere-runtime-1.0.0.beta4 dependency with Maven
Registering Push Servlet -- Not needed for Servlet 3.0, but added the manual configuration in web.xml:
Push Servlet org.richfaces.webapp.PushServlet 1 true
Chose server-side approach with Push CDI Event mechanism to fire messages. Updated my Status.java to be a message producer:
import java.io.Serializable; import javax.enterprise.context.SessionScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.inject.Named; import org.richfaces.cdi.push.Push;
@Named @SessionScoped public class Status implements Serializable {
@Inject @Push(topic = "statusPush") Event<String> pushEvent; private String status; public void addMessage(String message) { //Everytime the status is updated... status = status.concat(message + "\n"); //... the message is sent to the topic sendMessage(message); } public void sendMessage(String message) { pushEvent.fire(message); } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; }}
Handling messages on the view:
<a4j:push address="statusPush" onerror="alert(event.rf.data)"> <a4j:ajax event="dataavailable" render="statusOutput" /> </a4j:push> <h:inputTextarea id="statusOutput" value="#{status.status}" cols="80" rows="20" disabled="true"/>
Seems that it's all set but when I click the button that starts the migration process, I get the following stacktrace:
Warn: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception com.google.common.collect.ComputationException: javax.faces.FacesException: Lookup failed for '/ConnectionFactory' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} at com.google.common.collect.ComputingConcurrentHashMap$ComputingMapAdapter.get(ComputingConcurrentHashMap.java:397) at org.richfaces.application.push.impl.jms.JMSTopicsContextImpl.createTopic(JMSTopicsContextImpl.java:281) at org.richfaces.application.push.TopicsContext.getOrCreateTopic(TopicsContext.java:48) at org.richfaces.application.push.impl.SessionImpl.createSubscriptions(SessionImpl.java:190) at org.richfaces.application.push.impl.SessionImpl.subscribe(SessionImpl.java:185) at org.richfaces.resource.PushResource.encode(PushResource.java:88) at org.richfaces.resource.UserResourceWrapperImpl.encode(UserResourceWrapperImpl.java:188) at org.richfaces.resource.ResourceHandlerImpl.handleResourceRequest(ResourceHandlerImpl.java:229) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:591) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860) at com.sun.grizzly.comet.CometEngine.executeServlet(CometEngine.java:459) at com.sun.grizzly.comet.CometEngine.handle(CometEngine.java:316) at com.sun.grizzly.comet.CometAsyncFilter.doFilter(CometAsyncFilter.java:87) at com.sun.grizzly.arp.DefaultAsyncExecutor.invokeFilters(DefaultAsyncExecutor.java:171) at com.sun.grizzly.arp.DefaultAsyncExecutor.interrupt(DefaultAsyncExecutor.java:143) at com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:102) at com.sun.grizzly.http.TaskBase.run(TaskBase.java:193) at com.sun.grizzly.http.TaskBase.execute(TaskBase.java:175) at com.sun.grizzly.arp.DefaultAsyncHandler.handle(DefaultAsyncHandler.java:145) at com.sun.grizzly.arp.AsyncProtocolFilter.execute(AsyncProtocolFilter.java:210) at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) at com.sun.grizzly.ContextTask.run(ContextTask.java:71) at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) at java.lang.Thread.run(Thread.java:722) Caused by: javax.faces.FacesException: Lookup failed for '/ConnectionFactory' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} at org.richfaces.application.push.impl.jms.JMSTopicsContextImpl$1.apply(JMSTopicsContextImpl.java:207) at org.richfaces.application.push.impl.jms.JMSTopicsContextImpl$1.apply(JMSTopicsContextImpl.java:195) at com.google.common.collect.ComputingConcurrentHashMap$ComputingValueReference.compute(ComputingConcurrentHashMap.java:355) at com.google.common.collect.ComputingConcurrentHashMap$ComputingSegment.compute(ComputingConcurrentHashMap.java:184) at com.google.common.collect.ComputingConcurrentHashMap$ComputingSegment.getOrCompute(ComputingConcurrentHashMap.java:153) at com.google.common.collect.ComputingConcurrentHashMap.getOrCompute(ComputingConcurrentHashMap.java:69) at com.google.common.collect.ComputingConcurrentHashMap$ComputingMapAdapter.get(ComputingConcurrentHashMap.java:393) ... 39 more Caused by: javax.naming.NamingException: Lookup failed for '/ConnectionFactory' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: ] at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518) at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455) at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:654) at javax.naming.InitialContext.lookup(InitialContext.java:415) at javax.naming.InitialContext.lookup(InitialContext.java:415) at org.richfaces.application.push.impl.jms.JMSTopicsContextImpl$JMSTopicContext.createConnection(JMSTopicsContextImpl.java:98) at org.richfaces.application.push.impl.jms.JMSTopicsContextImpl$JMSTopicContext.start(JMSTopicsContextImpl.java:123) at org.richfaces.application.push.impl.jms.JMSTopicsContextImpl$1.apply(JMSTopicsContextImpl.java:199) ... 45 more Caused by: javax.naming.NameNotFoundException: at com.sun.enterprise.naming.impl.TransientContext.resolveContext(TransientContext.java:310) at com.sun.enterprise.naming.impl.TransientContext.lookup(TransientContext.java:218) at com.sun.enterprise.naming.impl.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:77) at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:119) at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:505) ... 52 more
Bottom line: JMS (I think) can't find the statusPush topic.
update: had JMS enabled in web.xml, changed to
<context-param>
<param-name>org.richfaces.push.jms.enable</param-name>
<param-value>true</param-value>
</context-param>
and now stacktrace is:
Warn: StandardWrapperValve[AutoRegisteredPushServlet]: PWC1406: Servlet.service() for servlet AutoRegisteredPushServlet threw exception java.lang.RuntimeException: java.lang.NullPointerException at org.atmosphere.handler.ReflectorServletProcessor.onRequest(ReflectorServletProcessor.java:171) at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:248) at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:166) at org.atmosphere.container.GrizzlyCometSupport.service(GrizzlyCometSupport.java:119) at org.atmosphere.container.GlassFishWebSocketSupport.service(GlassFishWebSocketSupport.java:110) at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:1257) at org.atmosphere.cpr.AtmosphereServlet.doPost(AtmosphereServlet.java:293) at org.atmosphere.cpr.AtmosphereServlet.doGet(AtmosphereServlet.java:279) at javax.servlet.http.HttpServlet.service(HttpServlet.java:668) at javax.servlet.http.HttpServlet.service(HttpServlet.java:770) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860) at com.sun.grizzly.comet.CometEngine.executeServlet(CometEngine.java:459) at com.sun.grizzly.comet.CometEngine.handle(CometEngine.java:316) at com.sun.grizzly.comet.CometAsyncFilter.doFilter(CometAsyncFilter.java:87) at com.sun.grizzly.arp.DefaultAsyncExecutor.invokeFilters(DefaultAsyncExecutor.java:171) at com.sun.grizzly.arp.DefaultAsyncExecutor.interrupt(DefaultAsyncExecutor.java:143) at com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:102) at com.sun.grizzly.http.TaskBase.run(TaskBase.java:193) at com.sun.grizzly.http.TaskBase.execute(TaskBase.java:175) at com.sun.grizzly.arp.DefaultAsyncHandler.handle(DefaultAsyncHandler.java:145) at com.sun.grizzly.arp.AsyncProtocolFilter.execute(AsyncProtocolFilter.java:210) at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) at com.sun.grizzly.ContextTask.run(ContextTask.java:71) at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) at java.lang.Thread.run(Thread.java:722) Caused by: java.lang.NullPointerException at org.richfaces.webapp.PushHandlerFilter.doFilter(PushHandlerFilter.java:90) at org.atmosphere.util.AtmosphereFilterChain.doFilter(AtmosphereFilterChain.java:154) at org.atmosphere.util.AtmosphereFilterChain.invokeFilterChain(AtmosphereFilterChain.java:131) at org.atmosphere.handler.ReflectorServletProcessor$FilterChainServletWrapper.service(ReflectorServletProcessor.java:310) at org.atmosphere.handler.ReflectorServletProcessor.onRequest(ReflectorServletProcessor.java:168) ... 40 more