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)

Reply via email to