Volodymyr Siedlecki created MYFACES-4542:
--------------------------------------------
Summary: 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
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 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
{noformat}
{noformat}
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 initalized 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):
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();
}
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)