Announcement Announcement Module
Collapse
No announcement yet.
OGNL Expression Question Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • OGNL Expression Question

    Hello,

    I've been using OGNL to simplify a lot of the transitions and actions in my flows, and ran across something interesting. I want to add an object to a list that's in the flow scope, so I tried this expression :
    1.
    <evaluate-action expression="flowScope.agencyPortfolioList.add(flow Scope.newPortfolioBean)" />

    I have agencies that have financial portfolios and the user is currently in a flow where they create and modify financial portfolios. I beat my head for about 3 hours tracking down the issue to that expression, and that expression does not work. I've made sure (through using debugging listeners) that both agencyPortfolioList (which is a java.util.List) and newPortfolioBean exist at the point that expression is evaluated. I replaced the above line with :

    2. <evaluate-action expression="@com.mypackage.accounting.AgencyPortfo lio@addToList(flowScope.agencyPortfolioList,flowSc ope.newPortfolioBean)"/>

    ie changed out the member function evaluation for a static method evaluation (which returns boolean instead of void). Can anybody see what's wrong with expression one ? I've been beating my head over it and it looks fine according to the OGNL syntax rules to me.

  • #2
    I made a simple test similar to yours and worked for me. How you tested the expression ?

    Comment


    • #3
      Hi Andrei,

      I'm using the evaluate-action above within the context of a transition :

      <action-state id="saveNewPortfolio">
      <action bean="apmNewPortfolioCommitAction"/>
      <transition on="error" to="showError"/>
      <transition on="success" to="newPortfolioRedirectDecision">
      <evaluate-action expression="@com.mypackage.CollectionUtils@add(flo wScope.agencyPortfolioList,flowScope.newPortfolioB ean)"/>
      </transition>
      </action-state>

      The 'showError' state is an end state and the 'newPortfolioRedirectDecision' is a decision-state that looks at a boolean that was previously set to determine where the next view would be.

      To answer your question more directly, I tested the expression by running the flow and setting up a Debugging FlowExecutionListener that reports the states as the flow goes through transitions and enters new states. The Listener reported that on the success event, the flow would attempt to exit the 'saveNewPortfolio' state and then promptly reenter it, indicating that the expression was the problem. As soon as I commented out the expression evaluation [<evaluate-action expression="flowScope.agencyPortfolioList.add(flow Scope.newPortfolioBean)" />] everything was fine. It was still fine event when I put in [<evaluate-action expression="@com.mypackage.CollectionUtils@add(flo wScope.agencyPortfolioList,flowScope.newPortfolioB ean)"/>]
      That static method has a void return type btw. Does Spring take different action depending on the result of the OGNL expression evaluation ? ie if it's non void or has some specific reaction to boolean results ?

      *EDIT* : The static method in my two posts is different because the first was a quick hack to test my theory, the second static method is a permanent utility method.
      Last edited by alexmarshall; May 25th, 2007, 11:13 AM. Reason: Changed code

      Comment


      • #4
        When you do something like:
        Code:
        <transition on="success" to="newPortfolioRedirectDecision">
        <evaluate-action expression="flowScope.agencyPortfolioList.add(flow Scope.newPortfolioBean)"/>
        </transition>
        the transition will be successful if the value of expression evaluation is successful, meaning returning 'success'.
        In case of '@com.mypackage.CollectionUtils@add(flowScope.agen cyPortfolioList,flowScope.newPortfolioBean)' the result is considered to be 'success'.
        In case of 'add' method of java.util.List, the return value is a boolean and the expression evaluation is 'yes'.

        Comment


        • #5
          That's actually pretty enlightening. But it seems rather odd to me that an evaluate action returning 'yes' instead of 'success' would block the transition. Thank you very much for your response Andrei.

          Comment


          • #6
            Hi, Alex.

            I happened to run across this exact problem today and I came up with another solution - use OGNL "chaining" to return a 'success' value.

            Code:
            	<action-state id="saveNewPortfolio">
            		<action bean="apmNewPortfolioCommitAction"/>
            		<transition on="error"		to="showError"/>
            		<transition on="success"	to="newPortfolioRedirectDecision">
            			<evaluate-action expression="${flowScope.agencyPortfolioList.add(flow Scope.newPortfolioBean), 'success'}" />		
            </transition>
            	</action-state>
            I hope it helps - it worked for me.

            -Peter

            Comment


            • #7
              Hi Peter,

              It worked great, and given how much pressure I'm under to get functionality out the door, I certainly never would have had the time to read that much in depth into OGNL, so I can't even estimate how much time you've likely saved me. Thank you so much !

              Comment


              • #8
                Another OGNL question

                I've got the following decision state:

                Code:
                	<decision-state id="START_STATE">
                		<if test="${!externalContext.sessionMap.USER_INFO.hasValuationsLeft()}" then="NO_VALS_LEFT_STATE"/>
                		<if test="${!externalContext.sessionMap.USER_INFO.getAppBoolean(@com.mypackage.AppRight@XTOL, @com.mypackage.AppRight@CAN_CREATE_VALUATIONS)}" then="OVERVIEW_STATE" else="Error"/>
                	</decision-state>
                XTOL and CAN_CREATE_VALUATIONS or public static final Strings in AppRight. When I get here instead of the expressions evaluating I get the following stacktrace:

                Code:
                java.lang.NullPointerException
                        at ognl.ASTStaticField.isNodeConstant(ASTStaticField.java:80)
                        at ognl.SimpleNode.isConstant(SimpleNode.java:270)
                        at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:165)
                        at ognl.SimpleNode.getValue(SimpleNode.java:210)
                        at ognl.ASTMethod.getValueBody(ASTMethod.java:71)
                        at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:170)
                        at ognl.SimpleNode.getValue(SimpleNode.java:210)
                        at ognl.ASTChain.getValueBody(ASTChain.java:109)
                        at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:170)
                        at ognl.SimpleNode.getValue(SimpleNode.java:210)
                        at ognl.ASTNot.getValueBody(ASTNot.java:49)
                        at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:170)
                        at ognl.SimpleNode.getValue(SimpleNode.java:210)
                        at ognl.Ognl.getValue(Ognl.java:333)
                        at ognl.Ognl.getValue(Ognl.java:310)
                        at org.springframework.binding.expression.support.OgnlExpression.evaluate(OgnlExpression.java:73)
                I am new at OGNL and this may be a newbie issue but I am stumped as to what I am doing wrong. I have read through the following manual and it has been very helpful, but according to the manual this is how you do this (unless I am misunderstanding something...probably the case).

                Comment


                • #9
                  Given your stack trace, it looks as though USER_INFO is null (ie not in the sessionMap). Can you confirm that it's actually in the session ?

                  Comment


                  • #10
                    First off, thank you for responding, this one is killing me. Yes it is in the session (plus there is now null pointer exception for the "if" case above it. I have logs in "hasValuationsLeft()" and the print out fine. I think I am just doing something wrong with the statics). Here are some of the things I have tried:

                    1. I created a new public static final boolean TEST = true; and I still get the same error when I do this:
                    Code:
                    <if test="${@com.mypackage.AppRight@TEST}" then="OVERVIEW_STATE" else="Error"/>
                    This also show that its not an issue of the userinfo being null.

                    2. If I do this I do not get an exception and I go to the overview state:
                    Code:
                    <if test="${true}" then="OVERVIEW_STATE" else="Error"/>
                    Once again thank you for your response. Does anyone have statics working when using the test attribute in a decision state. Maybe you can't, seems like you should be able to though. Any help or suggestions are welcome.

                    Is there some special setup that I need to do in order for ognl to see my classes...some specific classpath setup that ognl requires?
                    Last edited by testing123; Jun 1st, 2007, 01:39 PM.

                    Comment


                    • #11
                      I was having similar errors a while ago trying to use statics, though I was getting ClassNotFoundExceptions . I think OGNL has to be in the same class loading scope as webflow, and I had webflow in my ${appBase}/WEB-INF/lib directory to solve several class loading issues I had with webflow a while ago, so to solve my problem, I had to put the OGNL jar in my WEB-INF/lib directory as well. You might give that a try.

                      Comment


                      • #12
                        It was in my java "magic dir" so anything using java should be able to see it. Just in case though (I am willing to try anything at this point) I tried putting it in my WEB-INF lib dir and still get the same error. Again thanks for the response. Could you try adding a dummy decision state to your app and see if statics work in the test attribute for you? That way I will know that it is an issue with my setup or not. Thanks for all your help.

                        Comment


                        • #13
                          I gave it a try in the app I'm working on and I'm afraid that I couldn't duplicate the error you seem to be having. What version of OGNL do you have ? I'm using 2.6.9

                          Comment


                          • #14
                            I have the same version. Thanks for sticking with me. I'll just have to keep staring at it. If you can do it then its got to be something I am doing wrong. It's probably something simple. I'll let you know when I figure it out. Thanks again for all you help!

                            Comment


                            • #15
                              Update

                              Ok, so it was a classpath issue like you mentioned. I put the jar in my web-inf/lib directory like you said and it still didn't work because I forgot to remove it from the magic dir (argh). When I removed it from the magic dir it worked. Nothing was wrong with the syntax, OGNL just has to be in the same place as your app. It still puzzles me why it didn't work. I have my classes from my app in the classpath so why can't OGNL see them? If I move ognl to my web-inf lib (and keep the spring jars in the magic dir)then spring complains that it can't find ognl. When I move the spring jars over to my app as to the same place as ognl everything works fine. Does ognl have a special classloader that doesn't look at the classpath for my machine? Perhaps these are all questions for ognl people not spring people, but I was wondering if anyone else has knowledge about this that might be useful to the next guy (or gal) who has a similar issue. None of this was talked about in the manual I read, I keep looking and post anything I find.

                              Comment

                              Working...
                              X