Announcement Announcement Module
Collapse
No announcement yet.
1.0.2 sanity testing - feedback requested Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 1.0.2 sanity testing - feedback requested

    SWF community,

    We are in the process of sanity testing the 1.0.2 SVN head for release this week (targeting Tuesday 4/3). We expect this to be a very solid, stable release. We would appreciate those who have the opportunity to help us in our sanity tests to report any issues you may find in your environment to this thread.

    The 1.0.2 candidate build is available for sanity testing here:
    http://static.springframework.org/do...ng-webflow.php

    Here is the change log noting the changes in 1.0.2 of interest (referencing JIRAs addressed):

    Code:
    Changes in version 1.0.2 (03.04.2007)
    -------------------------------------
    
    Package org.springframework.binding
    * GenericConversionService.getConversionExecutor() now uses isAssignableFrom to detect situations
      where no conversion is necessary (SWF-264).
    * Fixed possbile NullPointerException in MethodKey.parameterTypesString() (SWF-265).
    * OgnlExpression now unwraps the ognl.OgnlException to make the real exception available to the
      caller (SWF-255).
    * OgnlExpressionParser now supports OGNL collection construction syntax (SWF-274).
    * AbstractExpressionParser now has a doParseSettableExpression() template method.
    
    Package org.springframework.webflow.action
    * FormAction methods doBind() and createBinder() now declare "throws Exception".
    * FormAction now consistently uses the getters to get property values (SWF-251).
    * ResultObjectBasedEventFactory now uses java.lang.Enum.name() to get the name of a Java 5 enum (SWF-250).
    
    Package org.springframework.webflow.config
    * Fixed bug in WebFlowConfigNamespaceHandler that caused the type attribute of the repository tag
      not to be read properly and throw an exception (SWF-239).
    * Added Spring tooling funtionality to the BeanDefinitionParser to allow tools such as SpringIDE
      to properly interact with it (SWF-254).
    * Added getFlowExecutor() method to FlowExecutorFactoryBean.
    
    Package org.springframework.webflow.context
    * The ThreadLocal in ExternalContextHolder is now final (SWF-262).
    
    Package org.springframework.webflow.conversation
    * The SessionBindingConversationManager now re-binds the ConversationContainer in the session
      every time a contained conversation is unlocked (SWF-244).
    
    Package org.springframework.webflow.engine
    * FlowExecutionImpl.handleException() now also tries to handle FlowExecutionExceptions that
      occur during exception handling (SWF-261).
    * The XmlFlowBuilder now also supports OGNL expressions in the "to" attribute of a transition
      when using the "on-exception" attribute (SWF-269).
    * The XmlFlowBuilder now consistently uses "fromStringTo(Class.class)" to resolve types (SWF-268).
    * Added AbstractFlowBuilderFlowRegistryFactoryBean for easy setup of a flow registry containing
      flows built using AbstractFlowBuilders.
    * Added DefaultFlowServiceLocator(String, BeanFactory) convenience constructor to the DefaultFlowServiceLocator.
    * Added BeanFactoryFlowVariable(String, BeanFactory, ScopeType) convenience constructor to the
      BeanFactoryFlowVariable.
    * Added settableExpression() method to AbstractFlowBuilder.
    
    Package org.springframework.webflow.execution
    * Added FlowExecutionListener.sessionCreated(RequestContext, FlowSession) callback, useful for
      setting flow attributes before the flow starts (SWF-223).
    * ClientContinuationFlowExecutionRepository now uses 'URL-safe Base64 encoding' (SWF-270).
    * AbstractConversationFlowExecutionRepository.parseFlowExecutionKey() now throws an
      BadlyFormattedFlowExecutionKeyException when asked to parse an empty flow execution key (SWF-277).
    
    Package org.springframework.webflow.executor
    * Added resource URL encoding to redirects in a JSF environment (SWF-256).
    * Added support for configuring a <flow:executor> in a JSF environment, greatly simplifying JSF SWF
      configuration and making it consistent with Spring MVC and Struts.  This also means its much easier
      to benefit from defaults such as a continuation-based flow execution repository and 'alwaysRedirectOnPause'.
    * Introduced ResponseInstructionHandler convenience class and refactored FlowController, PortletFlowController,
      FlowAction and FlowPhaseListener to use it.
    * JSF flow execution lifecycle now respects flow execution locking contract (SWF-229, SWF-276).
    * Fixed bug in FlowPhaseListener that resulted in a NPE on a flow that started and ended in the same request (SWF-273).
    
    Package org.springframework.webflow.test
    * Added constructor taking test name argument to AbstractFlowExecutionTests, AbstractExternalizedFlowExecutionTests
      and AbstractXmlFlowExecutionTests.
    
    Package org.springframework.webflow.samples
    * Made all samples Spring IDE 2.0 projects for use with the Spring Web Flow Graphical Editor and XML Flow Definition Editor out of the box.
      To use these features, import the sample projects into Eclipse 3.2.2 with WTP 1.5.3 and Spring IDE 2.0 M3 or greater installed (See http://springide.org)
    * Featured alternate versions of "ItemList" and "Sellitem" flows more prominently.
    * Enhanced the JSF-based version of SellItem to take advantage of the latest simplifications in Spring Web Flow's JSF support.  Please see this sample
      along with the practical section in the reference manual for illustrations of how to use Spring Web Flow in a JSF environment.
    * Greatly enhanced sample walkthrough documentation in 'practical' section of reference manual (special thanks to Rossen Stoyanchev who contributed this)
    Thanks in advance,
    Last edited by Keith Donald; Apr 1st, 2007, 10:22 PM.

  • #2
    This is not related to code, but reference document.

    I think reference document should write about max-continuation and max-conversations. These description is missing.

    Comment


    • #3
      [MINOR] Possible documentation error:

      Section 6.10.3 JSF Plumbing - resolver looks incomplete.

      Code:
      <variable-resolver>
          org.springframework.web.jsf.
      </variable-resolver>
      Shouldn't it be:

      Code:
      <variable-resolver>
        org.springframework.web.jsf.DelegatingVariableResolver
      </variable-resolver>

      Comment


      • #4
        I believe there is a mistake in the getValue method of FlowExecutionPropertyResolver (in the jsf package):

        Code:
        if (FLASH_SCOPE_PROPERTY.equals(property)) {
            return execution.getActiveSession().getScope().asMap();
        } else if (FLOW_SCOPE_PROPERTY.equals(property)) {
            return execution.getConversationScope().asMap();
        } else if (CONVERSATION_SCOPE_PROPERTY.equals(property)) {
            return execution.getActiveSession().getFlashMap().asMap();
        The scopes are mixed up...shouldn't this be:


        Code:
        if (FLASH_SCOPE_PROPERTY.equals(property)) {
            return execution.getActiveSession().getFlashMap().asMap();
        } else if (FLOW_SCOPE_PROPERTY.equals(property)) {
            return execution.getActiveSession().getScope().asMap();
        } else if (CONVERSATION_SCOPE_PROPERTY.equals(property)) {
            return execution.getConversationScope().asMap();
        -Jeremy

        Comment


        • #5
          Yes, good catch, that is indeed a bug and has been promptly resolved.

          In addition to this new set of resolvers, we are now exposing the flow execution key in the JSF UI View Root as an attribute. This mean the views themselves no longer have track the flow execution key for postback, which makes the view code simpler and more what you'd expect a JSF developer to be used to. This improvement will make 1.0.2 as well.

          The sellitem-jsf has been updated to reflect these improvements and has been considerably simplified as a result.

          Have you had a chance to reflect on the JSF improvements of 1.0.2? Am interested in hearing your feedback...

          Keith

          Comment


          • #6
            Keith,

            After further reviewing the new FlowExecutionPropertyResolver and FlowExecutionVariableResolver classes in the jsf package, I have a few concerns (aside from the bug...thanks for addressing it so quickly):

            1. The ability to access all three scopes via the EL is certainly a welcome and useful addition, but this implementation abandons one of the really useful features of the original FlowPropertyResolver, namely where there is no existing object in the scope for the given property name, then it delegates to the ApplicationContext to look for a bean with that name and puts it into the flow scope if found. I use this feature all over the place in our current projects, defining prototype beans in our Spring context for any class whose state we want to be managed by SWF. It works really well and is quite in line with JSF's standard managed bean features. I realize that implementing this in the new FlowExecutionPropertyResolver would take some extra doing, but I think it would be extremely worthwhile. I actually had implemented a similar resolver (that is aware of all three scopes) for our internal projects, but it is a JSF 1.2 ELResolver requiring Java 5 and I had not yet had the chance to backport it to JSF 1.1...it would be much simpler to take the idea and patch it into your new FlowExecutionPropertyResolver if you agree that it is worthwhile.

            2. The addition of the "flowExecution" property could potentially make EL expressions awfully verbose. I really would hate to see "#{flowExecution.conversationScope.someBean.somePr operty}" expressions littered throughout our view templates. We typically inject the SWF managed objects into a managed property of our JSF managed beans partially because I already thought "#{flowScope.someBean.someProperty}" was overly verbose, and I'm sure there are people out there who would like to bind their view templates directly to these scoped beans instead of having delegate methods in their JSF managed beans like we do. I understand that this was done to enable the ability to search all scopes in the case that a scope is not specified, but I think there could be a better way. Sure, "#{flowExecution.someBean.someProperty}" isn't quite as bad, but it would be really excellent if we could even get rid of the "flowExecution" part of the expression so that SWF managed beans could be resolved in the same way the JSF managed beans are resolved with all of the scopes being checked in order without having to specify the scope OR the flowExecution at all in the expression.

            I think #1 could be solved fairly quickly in the short term if the desire is to get 1.0.2 out as soon as possible...but I think the long term ideal solution would be to solve both #1 and #2 by making use of Spring 2.0's new custom scopes. Has anyone implemented the custom scopes using SWF's scopes? I know I recall a lot of people thinking that would be a good idea, but I've not yet seen an implementation of it. Ideally, a user would use this ability to define their SWF managed beans in their Spring context, specifying the desired SWF scope directly in the bean definition. Then the PropertyResolver could be rewritten to use the same algorithm as JSF uses for its managed beans when it encounters an EL expression:

            1. Search through the scopes in a well defined order (similarly to what is already done in the new FlowExecutionPropertyResolver) and if a match is found, return it.

            2. If an existing bean is not found in any of the scopes, ask the ApplicationContext for a bean of the given name. If a matching bean definition is found, instantiate it and put it into the appropriate scope. (This would require being able to ask the ApplicationContext for the scope of the given bean...is this possible?)

            3. If no match is found, continue on through the resolver chain.

            This approach would allow for beans to be defined and resolved by EL in much the same way as JSF managed beans, hopefully making for a smoother transition for current JSF users trying to reap the benefits of SWF.

            They could simply define:
            <bean id="someBean" class="com.foo.someBean" scope="flash"/>

            And then their EL expressions could be whittled down to just: #{someBean.someProperty}

            and things would just work the same as they are used to with JSF.

            What do you think?

            -Jeremy

            Comment


            • #7
              Originally posted by Keith Donald View Post
              Yes, good catch, that is indeed a bug and has been promptly resolved.
              Actually, I just grabbed your commit and it looks like there is still a mistake:

              Code:
              } else if (FLOW_SCOPE_PROPERTY.equals(property)) {
                  return execution.getActiveSession().getFlashMap().asMap();
              Originally posted by Keith Donald View Post
              In addition to this new set of resolvers, we are now exposing the flow execution key in the JSF UI View Root as an attribute. This mean the views themselves no longer have track the flow execution key for postback, which makes the view code simpler and more what you'd expect a JSF developer to be used to. This improvement will make 1.0.2 as well.
              Sounds great...that's something that's been on my own TODO list to look at for awhile. I've had a quick look at the implementation and it looks ideal...it should even work well with the various JSF-ajax frameworks, as long as they are properly handling the JSF state (as most of them do automatically).

              -Jeremy

              Comment


              • #8
                Jeremy,

                Really good points.

                Let me try and explain my rationale for #1, as obviously I chose not to cover that case for this varable/property resolver implementation.

                As you said, FlowExecutionVariable/PropertyResolver require an explict "flowExecution" prefix that basically says "bind to this variable in the flow execution" explicitly. The search provided there is purely a convenience for accessing local flow execution data structures only.

                The reason I chose not to delegate to the root Spring Web Application Context as FlowPropertyResolver does is I truly believe it's the flow execution's responsibility to ensure any variables are setup before they are referenced by selected views. This is easy to do by allocating flow variables using the "var" element or "set" action inside the flow definition.

                You can see this in SVN head by reviewing the sellitem sample. Notice how the "sale" bean has now been moved from the context fragment to inside the flow definition as a variable. It makes much more sense to me here, clearly stating "everytime the sellitem flow starts allocate a new sale variable". It is more confusing when variable definition and reference are spread across several (3) places.

                Now, with this said, let's say we want to support the case where no explicit flow execution prefix is required e.g. {#someBean.someProperty} (which I really think is a good idea we should support as well). In that case, it's not clear what scope "someBean" could come from. Does it come from request, flash, flow, conversation, session, or some other? In that case, I agree an exhaustive search is required and likely one that ends up with a DelegatingVariableResolver that delegates to a Spring Application Context in the event no match is found.

                So here are my thoughts. In the short term (1.0.2):

                1. Introduce the FlowExecutionVariable/PropertyResolver pair as it is today, to allow for explicitly referencing flowExecution variables allocated by the flow. This makes it easy for view developers to mix web flow variable access with other types of variable access, and it also promotes use of an important SWF feature (the ability to allocate flow instance state, which further centralizes logic inside the flow definition).

                2. Introduce another variable resolver that will perform a search through flash/flow/conversation for the requested variable and if not found will simply proceed to the next resolver in the chain. This will allow use of {#someBean.someProperty} style for accessing flow state transparently, with fallbacks for other scopes handled by other variable resolvers.

                In the longer term:

                3. Look into implementing custom Spring 2.0 scopes for SWF flash, flow, and conversation scope.

                How does this sound?
                Last edited by Keith Donald; Apr 2nd, 2007, 04:59 PM.

                Comment


                • #9
                  Jeremey, All:

                  A new DelegatingFlowVariableResolver has been committed, which will become the recommended default resolver for 1.0.2. Sellitem now illustrates this, and as you can see there is now no SWF-specific variable prefix on the binding expressions. Combined with the embedding of the flow execution key in the view root (also in 1.0.2), your JSF views participating in flows are now written without any Spring Web Flow dependency at all (just standard JSF). This is a significant improvement over the JSF support in 1.0 and 1.0.1.

                  The other resolvers (FlowExecutionVariableResolver/PropertyResolver and the original FlowVariableResolver/PropertyResolver) are unaffected and will continue to exists as alternatives.

                  A review / sanity test of this would be greatly appreciated.

                  Tommorrow we're going to make sure these new features are completely documented, which will probably add another day or so to the release date. Will keep you updated.

                  We will also schedule the custom scope option for SWF 1.1.

                  Keith

                  Comment


                  • #10
                    Originally posted by Keith Donald View Post
                    The reason I chose not to delegate to the root Spring Web Application Context as FlowPropertyResolver does is I truly believe it's the flow execution's responsibility to ensure any variables are setup before they are referenced by selected views. This is easy to do by allocating flow variables using the "var" element or "set" action inside the flow definition.
                    Ah, I see your reasoning now...I see how this makes sense with things that are flow scoped...but let me offer another perspective that focuses more on flash scope. Say, for example, I have 20 different views in a flow-based application and each of those views has its own tailored object to store model state, and that model state is injected into and manipulated by a JSF managed bean. The most useful place to store that model state object is in flash scope, as it allows the JSF managed bean to manipulate this state across several fine-grained requests made within the same page (a common JSF usage scenario, especially when introducing ajax to the mix), but then have that state cleaned up when a transition to another view is signaled into SWF. Extending the original FlowPropertyResolver to be aware of all three scopes worked excellently for this, because it ensured that the state object would be freshly instantiated (based on a prototype definition in our Spring context) and injected into our managed bean each time a new instance of that view is created by simply having the equivalent of the following faces-config fragment (though we use Shale annotations in place of faces-config):

                    Code:
                    <managed-bean>
                        <managed-bean-name>someBean</managed-bean-name>
                        <managed-bean-class>com.foo.SomeClass</managed-bean-name>
                        <managed-bean-scope>request</managed-bean-scope>
                        <managed-property>
                            <property-name>model</property-name>
                            <value>#{flashScope.someBeanModel}</value>
                        </managed-property>
                        <managed-property>
                            <property-name>someService</property-name>
                            <value>#{someService}</property-name>
                        </managed-property>
                    </managed-bean>
                    When the view is first created, the request scoped JSF bean gets instantiated, and in turn it gets injected with the new model instance, which gets stored in flash scope by the PropertyResolver...on subsequent JSF events within the same page, the JSF bean gets freshly instantiated and injected with the existing model instance from the flash scope found by the PropertyResolver. All very JSF-ish, if you will...just like with the JSF managed beans, the lifecycle of the flow scoped state object is managed completely outside of our application code. They are created on demand as needed by EL expression resolution, maintaint their state, and are destroyed according to the rules of their scope.

                    I don't believe (do correct me if I'm wrong) that I can achieve the same effect using either the "var" or "set" elements as you mentioned. The docs for the "var" element state, "Flow variables are automatically created when an execution of this flow starts." I believe if I used the "var" element to define all 20 of these stateful objects, they would only be freshly instantiated when the flow execution is first created, correct? Using the "set" element, I don't believe there is any mechanism to have the value attribute resolve to a prototype Spring bean definition, is there?

                    Originally posted by Keith Donald View Post
                    You can see this in SVN head by reviewing the sellitem sample. Notice how the "sale" bean has now been moved from the context fragment to inside the flow definition as a variable. It makes much more sense to me here, clearly stating "everytime the sellitem flow starts allocate a new sale variable". It is more confusing when variable definition and reference are spread across several (3) places.
                    Yes, I do think this makes perfect sense for something that is flow scoped, but not so much with flash scope.

                    Originally posted by Keith Donald View Post
                    Now, with this said, let's say we want to support the case where no explicit flow execution prefix is required e.g. {#someBean.someProperty} (which I really think is a good idea we should support as well). In that case, it's not clear what scope "someBean" could come from. Does it come from request, flash, flow, conversation, session, or some other?
                    Exactly. This is why I think the long term solution of defining custom scoped beans is the best one.

                    Originally posted by Keith Donald View Post
                    So here are my thoughts. In the short term (1.0.2):

                    1. Introduce the FlowExecutionVariable/PropertyResolver pair as it is today, to allow for explicitly referencing flowExecution variables allocated by the flow. This makes it easy for view developers to mix web flow variable access with other types of variable access, and it also promotes use of an important SWF feature (the ability to allocate flow instance state, which further centralizes logic inside the flow definition).

                    2. Introduce another variable resolver that will perform a search through flash/flow/conversation for the requested variable and if not found will simply proceed to the next resolver in the chain. This will allow use of {#someBean.someProperty} style for accessing flow state transparently, with fallbacks for other scopes handled by other variable resolvers.
                    As per my reasons above, I would still like to see in the short term some way of having a flash scoped instance created from a Spring prototype bean definition if it does not already exist, whether it be by adding this to the FlowExecutionPropertyResolver, or the FlowPropertyResolver. I suppose strictly speaking, it wouldn't really bother me if this didn't happen as I've already got an aforementioned JSF 1.2 ELResolver that does this. I just think this usage pattern would be extremely useful to the JSF community at large as it is something for which many different solutions have been created since JSF first was released, yet none have handled quite as thoroughly as SWF.

                    Originally posted by Keith Donald View Post
                    In the longer term:

                    3. Look into implementing custom Spring 2.0 scopes for SWF flash, flow, and conversation scope.

                    How does this sound?
                    Again, I do believe this to be the best overall solution, and the one that will be the most natural to JSF developers who have not previously used SWF.

                    -Jeremy

                    Comment


                    • #11
                      What do you think about the possibility of introducing view-state variables that when created were placed in flash scope? SWF supports "Simple variables" it creates directly as well as the ability to delegate to a BeanFactory for retrieving prototypes it then manages.

                      I understand your point about "feeling natural" to JSF developers and fully respect that. At the same time I also want to explore options within SWF because having one place to go to see control logic for a given state is compelling (also then this feature would be useful in other environments.)

                      Keith
                      Last edited by Keith Donald; Apr 2nd, 2007, 09:56 PM.

                      Comment


                      • #12
                        Looks good to me...

                        Upgraded my app and couldn't see any issues.

                        Good work, guys!

                        I do have a question: is the issue that prevents this:

                        Code:
                        <flow:executor id="flowExecutor" registry-ref="flowRegistry">
                        	<flow:repository type="continuation" max-conversations="1" max-continuations="30"/>
                        </flow:executor>
                        (from Erwin's: http://www.ervacon.com/products/swf/tips/tip2.html)

                        from working correctly now fixed? I wasn't sure, from the list...

                        Cheers,

                        Alph

                        Comment


                        • #13
                          Originally posted by Keith Donald View Post
                          What do you think about the possibility of introducing view-state variables that when created were placed in flash scope? SWF supports "Simple variables" it creates directly as well as the ability to delegate to a BeanFactory for retrieving prototypes it then manages.

                          I understand your point about "feeling natural" to JSF developers and fully respect that. At the same time I also want to explore options within SWF because having one place to go to see control logic for a given state is compelling (also then this feature would be useful in other environments.)
                          Something like this perhaps?

                          Code:
                          <view-state id="myView" view="/MyView.xhtml">
                              <entry-actions>
                                  <set attribute="modelState" scope="flash" 
                                         class="com.foo.MyViewState"/>
                              </entry-actions>
                          </view-state>
                          Or in the case of using a prototype bean:

                          Code:
                          <view-state id="myView" view="/MyView.xhtml">
                              <entry-actions>
                                  <set attribute="modelState" scope="flash" 
                                         bean="myViewState"/>
                              </entry-actions>
                          </view-state>
                          That certainly would be compelling for non-JSF users as it would give them something quite equivalent to JSF's managed-property injection, and it would also provide a solution for my illustrated scenario. But what if I need that same model object set up in more than one view state? Then I've got to define the same entry-action for each one of those views.

                          I suppose the same would hold true if I had defined the model bean in my Spring context with a custom flash scope, because I would have to add a duplicate <managed-property> entry to each of the different <managed-bean> entries in faces-config that need that initialized state object.

                          But where the custom scope idea becomes even more interesting to me is when you use something like Shale annotations instead of faces-config.

                          If I have:

                          Code:
                              <bean id="myViewState" class="com.foo.MyViewState" scope="flash"/>
                          Then all I need is:

                          Code:
                              @Bean(name = "myView", scope = Scope.REQUEST)
                              public class MyParentViewBean {
                                  
                                  @Property(value="#{myViewState}")
                                  private MyViewState modelState;
                              }
                          or if I didn't want to use Shale annotations, I could possibly achieve the same effect with:

                          Code:
                              @Configurable(autowire = Autowire.BY_NAME)
                              public class MyParentViewBean
                          Then you can have multiple beans that need the same setup just extend MyParentViewBean.

                          Taking it a step back to the way James and others prefer to have all of their beans managed by Spring, I can have:

                          Code:
                              <bean id="myViewBean" class="com.foo.MyViewBean"
                              scope="request">
                                  <property name="modelState" ref="myViewState"/>
                              </bean>
                          Still a bit cleaner than the cut-and-paste entry-actions as it would allow you to achieve re-use through abstract bean definitions.

                          -Jeremy

                          Comment


                          • #14
                            Keith, Jeremy

                            You've both made some really interesting points - thanks for sharing them....your really getting my brain working overtime!

                            Jeremy - finally, I now feel I have a good grap on how you have implemented your application. Although I do think it's simplier just using one IoC container to managed the beans. However, I could be wrong as I havent implemeted your approach successfully yet.

                            ....allow you to achieve re-use through abstract bean definitions.
                            Nice solution.

                            Comment


                            • #15
                              Alph,

                              Yes, the max-conv/max-contin issue is fixed in 1.0.2

                              Keith

                              Comment

                              Working...
                              X