[
https://issues.apache.org/jira/browse/MYFACES-4542?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Volodymyr Siedlecki resolved MYFACES-4542.
------------------------------------------
Fix Version/s: 4.0.0-RC4
Resolution: Fixed
> outbound-parameters not passed to nested flows
> ----------------------------------------------
>
> Key: MYFACES-4542
> URL: https://issues.apache.org/jira/browse/MYFACES-4542
> Project: MyFaces Core
> Issue Type: Bug
> Affects Versions: 4.0.0-RC3
> Reporter: Volodymyr Siedlecki
> Assignee: Volodymyr Siedlecki
> Priority: Major
> Fix For: 4.0.0-RC4
>
> Attachments: JSF22FacesFlows.war
>
>
> A regression was discovered in our testing in RC3 with the switch from JSF
> managed implicit objects to cdi managed implicit objects.
> In essence, RC2 always used the flowmap (storage?) of the current flow, but
> RC3 does not.
> Previously (RC2), the flow scope map was created as with the following stack:
>
> {noformat}
> FlowScopeMap.<init>(BeanManager, String) line: 42
> DefaultCDIFacesFlowProvider.lambda$getCurrentFlowScope$0(FacesContext, Flow,
> Object) line: 107
> 1548856593.apply(Object) line: not available
> HashMap<K,V>.computeIfAbsent(K, Function<? super K,? extends V>) line: 1134
> DefaultCDIFacesFlowProvider.getCurrentFlowScope(FacesContext) line: 104
> <----- Key Call
> FlowHandlerImpl.getCurrentFlowScope() line: 464
> FlowScopeImplicitObject.getValue(ELContext) line: 45
> ImplicitObjectResolver.getValue(ELContext, Object, Object) line: 200
> CompositeELResolver.getValue(ELContext, Object, Object) line: 62 {noformat}
>
> Note flow map is initialized with a unique flowMapKey
>
> {code:java}
> public FlowScopeMap(DefaultFacesFlowProvider provider, String flowMapKey)
> {
> this._provider = provider;
> this._flowMapKey = flowMapKey;
> }{code}
>
> As for the storage, it's created during a map#put call:
> {noformat}
> FlowScopeContextualStorageHolder(AbstractContextualStorageHolder<T>).getContextualStorage(String,
> boolean) line: 98
> FlowScopeContextualStorageHolder.getFlowScopeMap(BeanManager, String,
> boolean) line: 95
> FlowScopeMap.getWrapped(boolean) line: 65
> FlowScopeMap.put(Object, Object) line: 106
> MapELResolver.setValue(ELContext, Object, Object, Object) line: 89{noformat}
>
> The flowscope is then saved as an attribute on the facesContext (but is
> cleared once the facesContext is released at the end of the request). A new
> map is then created in subsequent requests.
> As for RC3, FlowScopeContext is now the "implict object manager (equivalent o
> FlowScopeImplicitObject) " of the flow map. (also see
> [FlowScopeExtension|https://github.com/apache/myfaces/blob/89c747e85615e3f33265e664c8361789f38ea7db/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeExtension.java#L37]
> for registration details).
> The problem lies in RC3 is with
> [FlowScopeContext|https://github.com/apache/myfaces/blob/89c747e85615e3f33265e664c8361789f38ea7db/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeContext.java#L156]#get(Contextual<T>
> bean) and FlowScopeContext#get(Contextual<T> bean, CreationalContext<T>
> creationalContext)
> They look at all activeFlowMapKeys when they should look at only the current
> flow (as in RC2):
>
> {code:java}
> List<String> activeFlowMapKeys =
> getStorageHolder(facesContext).getActiveFlowMapKeys(facesContext);
> for (String flowMapKey : activeFlowMapKeys)
> {
> ContextualStorage storage = getContextualStorage(facesContext,
> false, flowMapKey);
> if (storage == null)
>
> { continue; }
> Map<Object, ContextualInstanceInfo<?>> contextMap =
> storage.getStorage();
> ContextualInstanceInfo<?> contextualInstanceInfo =
> contextMap.get(storage.getBeanKey(bean));
> if (contextualInstanceInfo == null)
> { continue; }
> return (T) contextualInstanceInfo.getContextualInstance();
> }
> {code}
>
>
> Relevant Weld Code:
> [https://github.com/weld/core/blob/be7382b01c4a56c54f92873c1c2ebf0445714bfe/impl/src/main/java/org/jboss/weld/bean/ContextualInstanceStrategy.java#L94-L100]
>
> {noformat}
> FlowScopeContext.get(Contextual<T>) line: 182
> PassivatingContextWrapper$ContextWrapper(PassivatingContextWrapper$AbstractPassivatingContextWrapper<C>).get(Contextual<T>)
> line: 78
> ContextualInstanceStrategy$DefaultContextualInstanceStrategy<T>.get(Bean<T>,
> BeanManagerImpl, CreationalContext<?>) line: 95
> ContextualInstance.get(Bean<T>, BeanManagerImpl, CreationalContext<?>) line:
> 50
> BeanManagerImpl.getReference(Bean<?>, Type, CreationalContext<?>, boolean)
> line: 680
> WeldELResolver(AbstractWeldELResolver).lookup(BeanManagerImpl, ELContext,
> String) line: 107
> WeldELResolver(AbstractWeldELResolver).getValue(ELContext, Object, Object)
> line: 90 {noformat}
> Note if get(bean) returns null then get(bean, creationalContext) is called.
> Then the FlowScopeMap object is actually created with this call:
> storage.createContextualInstance(bean, creationalContext);
> bean argument in this case is "ForwardingBean flowScope for
> org.apache.myfaces.cdi.[FacesArtifactFlowMapProducer|https://github.com/apache/myfaces/blob/89c747e85615e3f33265e664c8361789f38ea7db/impl/src/main/java/org/apache/myfaces/cdi/FacesArtifactFlowMapProducer.java#L51]@23deee9"
> (contains the create(e ->
> FacesContext.getCurrentInstance().getApplication().getFlowHandler().getCurrentFlowScope())
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)