Add client behavior dynamically with var components - jsf

I'm trying to listen event from components contained in DynaForm of primefaces-extensions, so developer can do dynamically do some custom stuff. At the end I would like to be able to do this:
<pe:dynaForm id="dynaForm" value="#{dynaFormController.model}" var="data" controlKey="#{data.name}">
<pe:dynaFormControl type="input" for="txt">
<p:inputText id="txt" value="#{data.value}" required="#{data.required}" />
</pe:dynaFormControl>
<my:ajax event="keyup" listener="#{controller.authorSelected}" key="author"/>
</pe:dynaForm>
What I want to do:
Whenever the key defined in my:ajax match the controlKey of a pe:dynaFormControl, I want to attach the my:ajax client behavior to the p:inputText.
Problems encountered:
At first, I did all of this in DynaFormRenderer#encodeBody, quite convenient since var is put in the EL context. But I ended up having this exception (similar to this https://github.com/javaserverfaces/mojarra/issues/4365):
java.lang.NullPointerException
at javax.faces.component.UIComponentBase.restoreBehaviors(UIComponentBase.java:2228)
at javax.faces.component.UIComponentBase.restoreBehaviorsState(UIComponentBase.java:2203)
at javax.faces.component.UIComponentBase.restoreState(UIComponentBase.java:1623)
at javax.faces.component.UIOutput.restoreState(UIOutput.java:286)
at javax.faces.component.UIInput.restoreState(UIInput.java:1422)
at com.sun.faces.application.view.FaceletPartialStateManagementStrategy$2.visit(FaceletPartialStateManagementStrategy.java:379)
at com.sun.faces.component.visit.FullVisitContext.invokeVisitCallback(FullVisitContext.java:151)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1689)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIForm.visitTree(UIForm.java:371)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at com.sun.faces.application.view.FaceletPartialStateManagementStrategy.restoreView(FaceletPartialStateManagementStrategy.java:366)
at com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:138)
at com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:123)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:591)
at com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:151)
at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:353)
at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:199)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:123)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
Then I tried to do just like o:moveComponent from Omnifaces using PreRenderViewEvent, but var is not available at this moment, in fact, calling DynaForm#getValue() always return null.
Do you have any suggestions how properly attach client behavior dynamically when var comes in the picture?
More infos: Mojarra 2.2.15 & Tomcat 8

Related

jsf render allways an xhtml page

Hi im testing my new app, and i have a problem when i click a button on my form, it has a table on it and im always check for a values, if it true it render if not it doesnt, and a button for register data . The problem is that im deleting some data of the table by a script and it give me a null pointer exception when i click the button. In the logs files it says it render the page again and then goes to the specific function of the button, and since i have already delete the data when it tried to render the page again give me a error 500.
here is me table :
<h:panelGroup id="tab1" rendered="#{DataControl.tabIndex == 1}">
<h:dataTable>
<h:column>
<h:commandButton disabled="#{DataControl.CheckDelete(item.intIdAddress)}" />
</h:column>
</h:dataTable>
<h:commandButton action="#{DataControl.AddAddress}" />
</h:panelGroup>
<h:panelGroup id="tab2" rendered="#{DataControl.tabIndex == 2}">
< Refister Form >
</h:panelGroup>
here is my checkDelete function :
public boolean CheckDelete() {
Util.getLog().info("CheckDelete for id : "+ id);
if (id.render)
return true;
else
return false;
}
here is my AddAddress function :
public String AddAddress(){
Util.getLog().info("Go to Register Div");
tabIndex = 2;
}
And the Logs File when im in the form and click the button :
Enter to filter : Has Session
CheckDelete for id : 1
CheckDelete for id : 2
CheckDelete for id : 3
CheckDelete for id : 4
Go to Register Div
And when i delete the data N° 2 the Logs file is (im in the form, delete the data and then i click the button):
Enter to filter : Has Session
CheckDelete for id : 1
javax.el.ELException: /pages/session/account_settings.xhtml #101,253 disabled="#{GeneralDataControl.VerificaEliminacion(item.intIdAddress)}": java.lang.NullPointerException
javax.faces.FacesException: javax.el.ELException: /pages/session/account_settings.xhtml #101,253 disabled="#{GeneralDataControl.VerificaEliminacion(item.intIdAddress)}": java.lang.NullPointerException
at javax.faces.component.UIComponentBase$AttributesMap.get(UIComponentBase.java:2214)
at com.sun.faces.util.Util.componentIsDisabledOrReadonly(Util.java:418)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.shouldDecode(HtmlBasicRenderer.java:739)
at com.sun.faces.renderkit.html_basic.ButtonRenderer.decode(ButtonRenderer.java:77)
at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:791)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1048)
at javax.faces.component.UIData.iterate(UIData.java:1477)
at javax.faces.component.UIData.processDecodes(UIData.java:980)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1043)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1043)
at javax.faces.component.UIForm.processDecodes(UIForm.java:212)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1043)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1043)
at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:920)
at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:74)
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 com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1213)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1154)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:145)
at com.alignet.wallet.cliente.filter.FiltroHibernate.doFilter(FiltroHibernate.java:90)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:190)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:130)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain._doFilter(WebAppFilterChain.java:87)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:848)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:691)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:654)
at com.ibm.ws.wswebcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:526)
at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:90)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:764)
at com.ibm.ws.wswebcontainer.WebContainer.handleRequest(WebContainer.java:1478)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:133)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:457)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:515)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:300)
at com.ibm.ws.http.channel.inbound.impl.HttpICLReadCallback.complete(HttpICLReadCallback.java:102)
at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)
at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:136)
at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:196)
at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:751)
at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:881)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1593)
Caused by: javax.el.ELException: /pages/session/account_settings.xhtml #101,253 disabled="#{GeneralDataControl.VerificaEliminacion(item.intIdAddress)}": java.lang.NullPointerException
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:111)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:190)
at javax.faces.component.html.HtmlCommandButton.isDisabled(HtmlCommandButton.java:183)
at sun.reflect.GeneratedMethodAccessor489.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:619)
at javax.faces.component.UIComponentBase$AttributesMap.get(UIComponentBase.java:2206)
... 44 more
Caused by: java.lang.NullPointerException
at com.alignet.wallet.cliente.web.GeneralDataJSFAction.VerificaEliminacion(GeneralDataJSFAction.java:388)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:619)
at javax.el.BeanELResolver.invokeMethod(BeanELResolver.java:737)
at javax.el.BeanELResolver.invoke(BeanELResolver.java:467)
at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:246)
at com.sun.el.parser.AstValue.getValue(AstValue.java:111)
at com.sun.el.parser.AstValue.getValue(AstValue.java:163)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:106)
... 50 more
its seems that jsf always render the page before to do the submit, i dont know how to solve this. I think is a configuration thing.
Im using a filter (the only filter ) to check for the session of the user and then a "doFilter" to let the response continue.
Thanks 4 ur time.

selectOneMenu sets field to null after being changed

I try to do something that is very similar to this richfaces example. I have a form that describes custom ID validation in case that you have not selected one of the predefined ones, else the form will be disabled. So disabled expression for the form members would go to the next method:
public boolean isPredefinedValidator() {
return !currentProjectRegField.getIdValidation().getIdType().equals(IdValidatorType.NONE);
}
that is invoked like this:
disabled="#{accountHome.isPredefinedValidator()}"
and here is the selector for the predefined validator:
<h:selectOneMenu value="#{accountHome.currentProjectRegField.idValidation.idType}"
rendered="#{!(empty accountHome.currentProjectRegField or empty accountHome.currentProjectRegField.idValidation)}">
<a4j:support event="onchange" reRender="customIdValidator"/>
<s:convertEnum />
<s:enumItem enumValue="NONE" label="#{messages['IdValidatorType_enum.NONE']}"/>
<s:enumItem enumValue="USA_ID" label="#{messages['IdValidatorType_enum.USA_ID']}"/>
<s:enumItem enumValue="MEXICO_ID" label="#{messages['IdValidatorType_enum.MEXICO_ID']}"/>
</h:selectOneMenu>
The issue is, when the method isPredefinedValidator() is invoked on a4j rerender (on disabled EL), I receive NPE.
Caused by: java.lang.NullPointerException
at com.whatever.something.action.AccountHome.isPredefinedValidator(AccountHome.java)
And when I try to debug - turns out that the value that has been set from the selectOneMenu is null.
Does it mean that reRender and setting value to the variable happens async, and there is a race condition? And what is the correct solution for this case?
Some black-magic configuration in the rich:modalPanel that contains the h:selectOneMenu resolved this issue. It goes like this <rich:modalPanel ... domElementAttachment="form">

jsf session timeout loop

I've a problem with JSF session handling:
At first i got everytime a viewExpiredException:
javax.faces.application.ViewExpiredException: viewId:/anyForm.jsf - View /anyForm.jsf could not be restored.
So I added the following code to my web.xml file:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/index.jsf?reason=expired</location>
</error-page>
and the following in my index.jsf file (which also got some forms and inputs):
<h:outputText value="#{messages.session_expired}"
rendered="#{param.reason == 'expired'}" />
whenever I get a timeout now, I am redirected to the index.jsf and the text is shown, but if I enter a value in an input and press the submit button of the form, I still get a redirect to my index.jsf. So, I am stuck in a loop. I also tried things like:
<context-param>
<param-name>com.sun.faces.enableRestoreView11Compatibility</param-name>
<param-value>true</param-value>
</context-param>
due to the fact that I read index.jsf then automatically create a new session. However, this didn't help me at all.
I also get this exception if I got a (loop) timeout and change a value of a input and submit the form (I am using primefaces "spinner" input):
javax.servlet.ServletException: Index: 1, Size: 1
javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
java.util.ArrayList.RangeCheck(ArrayList.java:547)
java.util.ArrayList.get(ArrayList.java:322)
javax.faces.component.AttachedObjectListHolder.restoreState(AttachedObjectListHolder.java:165)
javax.faces.component.UIInput.restoreState(UIInput.java:1411)
com.sun.faces.application.view.StateManagementStrategyImpl$2.visit(StateManagementStrategyImpl.java:276)
com.sun.faces.component.visit.FullVisitContext.invokeVisitCallback(FullVisitContext.java:151)
javax.faces.component.UIComponent.visitTree(UIComponent.java:1589)
javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
javax.faces.component.UIForm.visitTree(UIForm.java:344)
javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:263)
com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:188)
com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:123)
com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:452)
com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:148)
com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:192)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)

After confirmation, navigate to first tab of wizard

Pretty much, everything is said in title of topic.What I need to achieve is that when I am in last (confirm) tab of wizard and click on my button, after everything is done, I want to back to first tab of wizard. Of course, everything in wizard should be reset after that.
Well, it isn't help. Currently I am totally confused. On click of button I get this exception, but not in server log, only in browser I get:
An Error Occurred:
java.lang.NullPointerException
java.lang.NullPointerException
at org.primefaces.component.datatable.DataHelper.decodeFilters(DataHelper.java:167)
at org.primefaces.component.datatable.DataTableRenderer.decode(DataTableRenderer.java:51)
at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:790)
at javax.faces.component.UIData.processDecodes(UIData.java:980)
at org.primefaces.component.datatable.DataTable.processDecodes(DataTable.java:542)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1042)
at org.primefaces.component.panel.Panel.processDecodes(Panel.java:282)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1042)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1042)
at org.primefaces.component.wizard.Wizard.processDecodes(Wizard.java:210)
at javax.faces.component.UIForm.processDecodes(UIForm.java:216)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1042)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1042)
at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:941)
at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
at java.lang.Thread.run(Thread.java:619)
Button looks like this:
<p:commandButton ajax="false" value="Save service" action="#{kuBean.saveService}"
update="growl"/>
Interesting...
Assuming that your bean is #ViewScoped then a simple page redirect to the url of your wizard page should reinstantiate your wizards managed bean. If that doesn't work you can append the GET property [url]?faces-redirect=true to the URL.
This won't work if your managed bean is #SessionScoped however as the data and state information from the previous wizard confirmation will likely still be there. The best solution would be to switch to ViewScoped and if that is not possible then write a reset method of the managed bean that can clear the state and data of the managed bean.
try using the flowListener of the p:wizard
<p:wizard flowListener="#{userWizard.handleFlow}">
...
</p:wizard>
in your bean:
public String handleFlow(FlowEvent event) {
String currentStepId = event.getCurrentStep();
String stepToGo = event.getNextStep();
//if(skip)
//return "confirm";
//else
//return event.getNextStep();
... portion where you are to return to the first tab
return "id_value_of_first_tab";
}

Weld 1.0.1-Final: Conversation Scope bean keeps recreated even after beginning conversation?

Im currently using :
Apache tomcat 7
JBoss Weld servlet 1.0.1-Final
empty beans.xml
<listener-class>org.jboss.weld.environment.servlet.Listener</listener-class> in the web.xml
I'm currently testing a simple counter #ConversationScoped bean, and the intention is, after beginning the conversation scope, to keep incrementing the counter whenever the button is clicked ..
But it seems that after submit, the bean will always be recreated, even after i've begin the conversation in the 1st place.
Here's my simple bean :
package user.ui;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Inject;
import javax.inject.Named;
#Named
#ConversationScoped
public class CounterBean implements Serializable {
#Inject
private Conversation conversation;
#PostConstruct
public void init() {
System.out.println("beginning conversation : " + this.conversation);
this.conversation.begin();
}
private int counter;
public int getCounter() {
return counter;
}
public void setCounter(int counter) {
this.counter = counter;
}
public void increment() {
this.counter++;
}
}
Here's my simple jsf view :
<ui:composition template="/template/masterlayout.xhtml">
<ui:define name="windowTitle">Test Conversation Scope</ui:define>
<ui:define name="heading">Test Conversation Scope</ui:define>
<ui:define name="content">
<h:form>
<p:messages id="messages" globalOnly="true" />
<p:panel header="Test Conversation Scope">
<h:outputText value="counter : " /> #{counterBean.counter}
</p:panel>
<h:commandButton value="Submit Data to Server" action="#{counterBean.increment}" />
</h:form>
</ui:define>
</ui:composition>
Here's the log file for the 1st access :
INFO: Server startup in 12055 ms
beginning conversation : ID: 1, transient: true, timeout: 600000ms
And after the view is displayed, i clicked on the button, and there goes the exception throwing with this log in catalina.out :
beginning conversation : ID: 2, transient: true, timeout: 600000ms
unhandled exception : org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type #ConversationScoped
cause exception : org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type #ConversationScoped, cause exception is BE : false
Here's the exception trace from tomcat log :
Apr 4, 2011 3:56:27 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Faces Servlet] in context with path [/primebert] threw exception [WELD-001303 No active contexts for scope type #ConversationScoped] with root cause
org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type #ConversationScoped
at org.jboss.weld.conversation.ConversationImpl.checkConversationActive(ConversationImpl.java:79)
at org.jboss.weld.conversation.ConversationImpl.isTransient(ConversationImpl.java:234)
at org.jboss.weld.conversation.ConversationImpl.toString(ConversationImpl.java:199)
at java.text.MessageFormat.subformat(MessageFormat.java:1246)
at java.text.MessageFormat.format(MessageFormat.java:836)
at java.text.Format.format(Format.java:140)
at java.text.MessageFormat.format(MessageFormat.java:812)
at ch.qos.cal10n.MessageConveyor.getMessage(MessageConveyor.java:89)
at org.jboss.weld.logging.WeldMessageConveyor.getMessage(WeldMessageConveyor.java:78)
at org.slf4j.cal10n.LocLogger.debug(LocLogger.java:95)
at org.jboss.weld.conversation.ConversationImpl.switchTo(ConversationImpl.java:190)
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.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:304)
at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:54)
at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:163)
at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:298)
at org.jboss.weld.bean.proxy.ClientProxyMethodHandler.invoke(ClientProxyMethodHandler.java:113)
at org.jboss.weld.util.CleanableMethodHandler.invoke(CleanableMethodHandler.java:43)
at org.jboss.weld.conversation.ConversationImpl_$$_javassist_2.switchTo(ConversationImpl_$$_javassist_2.java)
at org.jboss.weld.conversation.AbstractConversationManager.beginOrRestoreConversation(AbstractConversationManager.java:137)
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.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:304)
at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:54)
at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:163)
at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:298)
at org.jboss.weld.bean.proxy.ClientProxyMethodHandler.invoke(ClientProxyMethodHandler.java:113)
at org.jboss.weld.util.CleanableMethodHandler.invoke(CleanableMethodHandler.java:43)
at org.jboss.weld.conversation.ServletConversationManager_$$_javassist_0.beginOrRestoreConversation(ServletConversationManager_$$_javassist_0.java)
at org.jboss.weld.jsf.WeldPhaseListener.initiateSessionAndConversation(WeldPhaseListener.java:171)
at org.jboss.weld.jsf.WeldPhaseListener.beforeRestoreView(WeldPhaseListener.java:118)
at org.jboss.weld.jsf.WeldPhaseListener.beforePhase(WeldPhaseListener.java:87)
at com.sun.faces.lifecycle.Phase.handleBeforePhase(Phase.java:228)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:99)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:111)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:541)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:383)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:288)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Any ideas what went wrong ?
Thank you !
To keep track of the long-running conversation Weld inserts the cid parameter in the action method of the HTML form.
In your case you start the long-running conversation in the PostConstruct method of the counterBean. But the counterBean gets referenced first inside the h:form, so by the time counterBean gets initialized the h:form's header was already rendered. You need to start the conversation earlier.
I'm not sure what's the best way to do that. Probably like that:
<f:metadata>
<f:event type="preRenderView" listener="#{someBean.init}"/>
</f:metadata>
You could start the conversation on GET request only:
public void init() {
if (!FacesContext.getCurrentInstance().isPostback()) {
conversation.begin();
}
}
JSF 2.2 has a <f:viewAction> tag (analogous to Seam page actions), that could be used to accomplish the same thing.
Alternatively you can just place this EL expression above the form:
#{javax.enterprise.context.conversation.begin()}
But then you have to be careful not to re-render this expression again.
As a side note, a conversation is often started on some JSF action, such as a button click. One needs to keep in mind, that for a proper conversation propagation forms need to be re-rendered.
From a CDI point of view, your code should work (it actually works on a JBoss AS 6). What seems to happen is that the conversation isn't propagated between two requests, but that should be implicit when using JSF form submits. I assume your setup is wrong and Tomcat isn't configured as it should be.
As a first step, try to propagate the conversation id manually, as described here.
We've seen the same so work around it we are performing a redirect back to the page as soon as we start a conversation. We know which parts of our app need conversations based on form id prefix, so can do this in an early phase listener. After Restore View works well. I'm having trouble performing redirects from Before Restore View which would be more ideal.
I've ended up using HttpServletRequest from FacesContext.getExternalContext().getRequest() which can give the full URL to redirect to. I do break it down in code and recombine it - the structure of our code and a reusable class to contain the concept of a form and parameters. The sendRedirect with exception handling removed is
ExternalContext external = faces.getExternalContext();
String baseUrl = external.getRequestContextPath() + m_formId;
String target = external.encodeRedirectURL(baseUrl, m_requestParameters);
external.redirect(target);

Resources