Foren

MyFaces Orchestra - Conversation scoped bean reinitialized on each action

Karthikeyan Baskaran, geändert vor 11 Jahren.

MyFaces Orchestra - Conversation scoped bean reinitialized on each action

New Member Beiträge: 5 Beitrittsdatum: 22.11.12 Neueste Beiträge
Hi,

Im in the process of migrating a project based on Primefaces to portlet environment using Liferay portlet bridge. The project employes MyFaces Orchestra for conversation scoped beans. Normally the conversation-scoped bean state would be maintained across pages until I create a seperate conversation context. After migrating to portlet environment, the bean is getting reinitialized each time I do any action like clicking on a submit button or click on a link, etc.

For example,
I am having a search bean (conversation scoped) which has two variables for storing search criteria and search results. Once I enter the search criteria and click on "submit", a new conversation context is created (conversationContext in url keeps on changing like conversationContext=k,l,m,etc.) and the bean state is reinitialized. So the page go backs to the original state with all my search criteria reset and no results being displayed.
thumbnail
Neil Griffin, geändert vor 11 Jahren.

RE: MyFaces Orchestra - Conversation scoped bean reinitialized on each acti

Liferay Legend Beiträge: 2655 Beitrittsdatum: 27.07.05 Neueste Beiträge
Are you seeing any exceptions in the server log, like the one reported in the forum post titled Convo Scope?
Karthikeyan Baskaran, geändert vor 11 Jahren.

RE: MyFaces Orchestra - Conversation scoped bean reinitialized on each acti

New Member Beiträge: 5 Beitrittsdatum: 22.11.12 Neueste Beiträge
I am not getting any exception. My problem is just that the conversation context keeps on changing.

If I use something like this, <h:commandLink action="page2.xhtml" value="Calculate" /> then the conversationContext parameter in the URL keeps on changing and I am loosing the values stored in the bean.

But instead if i use <h:commandLink action="page2.xhtml?faces-redirect=true" value="Calculate" />, the conversationContext remains the same and the values are retained across the pages. Whether I have to add this parameter to all the navigation rules? Is this the right way?
thumbnail
Neil Griffin, geändert vor 11 Jahren.

RE: MyFaces Orchestra - Conversation scoped bean reinitialized on each acti

Liferay Legend Beiträge: 2655 Beitrittsdatum: 27.07.05 Neueste Beiträge
This is just a guess, but it might be that Apache MyFaces Orchestra is setting a request attribute that it is not cleaning up at the end of an ActionRequest. Liferay will preserve/copy request attributes that were originally set on an ActionRequest into the RenderRequest. This is indeed the case with the Apache Trinidad org.apache.myfaces.trinidadinternal.context.FacesContextFactoryImpl.CacheRenderKit constructor, which consults a request attribute named "org.apache.myfaces.trinidad.util.RequestStateMap" that must be excluded.

The JSR 329 spec provides a mechanism for handing this problem, by specifying attributes that are to be "excluded" inside of the WEB-INF/faces-config.xml descriptor. For example:

<faces-config>
	<application>
		<application-extension>
			<bridge:excluded-attributes>
				<bridge:excluded-attribute>org.apache.myfaces.trinidad.util.RequestStateMap</bridge:excluded-attribute>
			</bridge:excluded-attributes>
		<application-extension>
	<application>
<faces-config>
</faces-config></application></application-extension></application-extension></application></faces-config>


So my recommendation would be that you turn on DEBUG level logging for com.liferay.faces.bridge.scope.BridgeRequestScopeImpl inside of your portlet's log4j.properties file and look for the output of these loggers from the removeExcludedAttributes(RenderRequest) method:


logger.debug("Removed request attribute name=[{0}] since it was specified for removal.",
	attributeName);
...
logger.debug(
	"Kept request attribute name=[{0}] since it existed prior to the FacesContext being created.",
	attributeName);
...
logger.debug(
	"Removed request attribute name=[{0}] that had been preserved in the ACTION_PHASE or EVENT_PHASE",
	attributeName);


You might see the "Kept request attribute" logger output a request attribute name related to Apache MyFaces Orchestra. You might want to try specifying it for exclusion in WEB-INF/faces-config.xml and then redeploy your WAR.
Karthikeyan Baskaran, geändert vor 11 Jahren.

RE: MyFaces Orchestra - Conversation scoped bean reinitialized on each acti

New Member Beiträge: 5 Beitrittsdatum: 22.11.12 Neueste Beiträge
I have tried logging DEBUG statements for com.liferay.faces.bridge.scope.BridgeRequestScopeImpl as you said. But i could not find any request attribute related to Myfaces orchestra. Please find the log below.

10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:218] Kept request attribute name=[WINDOW_STATE] since it existed prior to the FacesContext being created.
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:218] Kept request attribute name=[javax.portlet.config] since it existed prior to the FacesContext being created.
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:218] Kept request attribute name=[javax.portlet.response] since it existed prior to the FacesContext being created.
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:232] Removed request attribute name=[_primefacesbasic_WAR_JSFPortlet_com.liferay.portal.kernel.servlet.PortletServletConfig] that had be
en preserved in the ACTION_PHASE or EVENT_PHASE
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:218] Kept request attribute name=[javax.portlet.lifecycle_phase] since it existed prior to the FacesContext being created.
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:218] Kept request attribute name=[com.liferay.portal.kernel.servlet.PortletServletFilterChain] since it existed prior to the FacesContex
t being created.
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:218] Kept request attribute name=[PORTLET_ID] since it existed prior to the FacesContext being created.
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:218] Kept request attribute name=[javax.portlet.faces.phase] since it existed prior to the FacesContext being created.
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:218] Kept request attribute name=[com.liferay.portal.kernel.servlet.PortletServletResponse] since it existed prior to the FacesContext b
eing created.
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:218] Kept request attribute name=[com.liferay.portal.kernel.servlet.PortletServletRequest] since it existed prior to the FacesContext be
ing created.
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:218] Kept request attribute name=[com.liferay.portal.kernel.servlet.PortletServletConfig] since it existed prior to the FacesContext bei
ng created.
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:218] Kept request attribute name=[javax.portlet.portlet] since it existed prior to the FacesContext being created.
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:218] Kept request attribute name=[INVOKER_FILTER_URI] since it existed prior to the FacesContext being created.
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:218] Kept request attribute name=[javax.portlet.request] since it existed prior to the FacesContext being created.
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:39] restoreState(facesContext)
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:269] Restored viewId=[/page2.xhtml] uiViewRoot=[com.liferay.faces.bridge.component.UIViewRootBridgeImpl@23bedb]
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:39] Did not restore any facesMessages
10:00:31,716 INFO  [STDOUT] 10:00:31,716 DEBUG [BridgeRequestScopeImpl:39] Restored non-excluded request attributes
thumbnail
Neil Griffin, geändert vor 11 Jahren.

RE: MyFaces Orchestra - Conversation scoped bean reinitialized on each acti

Liferay Legend Beiträge: 2655 Beitrittsdatum: 27.07.05 Neueste Beiträge
Thanks for posting the debug output. Looks like it's probably not a request attribute problem. Could you attach a really simple portlet (preferably maven based) that reproduces the problem? I'd be happy to take a look at it.
Nemer Daud, geändert vor 11 Jahren.

RE: MyFaces Orchestra - Conversation scoped bean reinitialized on each acti

New Member Beiträge: 3 Beitrittsdatum: 07.11.12 Neueste Beiträge
Hi, Neil.

I'm facing the same problem. Did this thread had some progress ? I'd be happy helping in the progress of this issue.
thumbnail
Neil Griffin, geändert vor 11 Jahren.

RE: MyFaces Orchestra - Conversation scoped bean reinitialized on each acti

Liferay Legend Beiträge: 2655 Beitrittsdatum: 27.07.05 Neueste Beiträge
Do you have a simple maven-based project that can reproduce the problem? If so it would be great if you could attach the source to this thread. Thanks.
Nemer Daud, geändert vor 11 Jahren.

RE: MyFaces Orchestra - Conversation scoped bean reinitialized on each acti

New Member Beiträge: 3 Beitrittsdatum: 07.11.12 Neueste Beiträge
Neil, sorry by the delay, but sometimes is not so easy to do simple things...

I attached a simple maven based project (I don't know if all dependencies are in plublic repositories. If don't, let me know to expose it in pom.xml). I tested it in the tomcat-7 and liferay-6.1.1.ga1-tomcat-7. When running in tomcat-7, the Orchestra context works like a charm, but running on Liferay with Bridge, the context is renewed every request.

How the sample works:
(To run in tomcat-7, just comment bridge dependency in pom.xml no other change is needed)
1) deploy generated war file and access http://localhost:8080/portlet-orchestra-web-1.0-SNAPSHOT. The welcome page is self-explained. It is a enter point of de Orchestra' s configured flow. Every time that this page is load, the flow are renewed (conversationContext is incresed) and beans defined within this flow are renewed too.
2) clicking "Start New Flow" button sumit the request to the EditData page. This page have inputs to fill with some data to test the conversationContext.
3) clicking "Submit" (into EditData page) the FormBean are feeded with form data and are showed again in the next page (Result page).
4) clicking "Back" (into Result page) the flow back to the EditData page.

The sample passes the test if the form data is maintained in transitions between pages EditData.xhtml and Result.xhtml through button "Submit" (editData) and "Back" (Result). If the welcome page is accessed again, the conversationContext is renewed and form data is cleaned. In the pages EditData.xhtml and Result.xhtml is presented the parameter conversationContext for guidance.
Karthikeyan Baskaran, geändert vor 11 Jahren.

RE: MyFaces Orchestra - Conversation scoped bean reinitialized on each acti

New Member Beiträge: 5 Beitrittsdatum: 22.11.12 Neueste Beiträge
Hi Neil,

Sorry for the delay in posting the sample project. I am still not able to fix this issue. I see that another user has already posted a sample project.

I am attaching another simple project which adds two values and displays the result in another page. Please check and let me know what causes the conversation scoped bean(AdditionBean) to reinitialize on click of “Calculate” button. Thanks!
Karthikeyan Baskaran, geändert vor 11 Jahren.

RE: MyFaces Orchestra - Conversation scoped bean reinitialized on each acti

New Member Beiträge: 5 Beitrittsdatum: 22.11.12 Neueste Beiträge
Any updates on how to solve this issue?
thumbnail
Neil Griffin, geändert vor 11 Jahren.

RE: MyFaces Orchestra - Conversation scoped bean reinitialized on each acti

Liferay Legend Beiträge: 2655 Beitrittsdatum: 27.07.05 Neueste Beiträge
We haven't made any progress on this issue. We have made some progress on CDI compatibility via JBoss Weld. Would that be a suitable alternative for your requirements?
Nemer Daud, geändert vor 10 Jahren.

RE: MyFaces Orchestra - Conversation scoped bean reinitialized on each acti

New Member Beiträge: 3 Beitrittsdatum: 07.11.12 Neueste Beiträge
Switch to JBoss Weld could lead a hard refactoring. I solved my problem leaving Orchestra behind. Analysing Orchestra, it discovers that the request is a portlet request and makes a series of threatments to handle it. I suppose that it doen't do that well or, in conjunction with the bridge, get lost. I didn't have much time to analise, than obviously I could be wrong.
What matters is that it was enough to make me decide to create my own ConversationContext using Spring Scoped resources and an OpenEntityManagerInView using AOP. It was easier than I thought and I followed the same orchestra pattern to ensure lighter refactoring.
Now, it's working like a charm in production with liferay-faces-bridge 3.1.1-ga2, liferay 6.1.1-ga2, icefaces 3.2.0, jsf 2.1.6 and spring 3.1.3, what reinforces my perception that the problem should not be on the bridge.
thumbnail
Neil Griffin, geändert vor 10 Jahren.

RE: MyFaces Orchestra - Conversation scoped bean reinitialized on each acti

Liferay Legend Beiträge: 2655 Beitrittsdatum: 27.07.05 Neueste Beiträge
Hi Nemer,

Would you consider sharing your Spring-based solution with the community? Perhaps create an open source project at GitHub?

Thanks,

Neil