Announcement Announcement Module
Collapse
No announcement yet.
WebFlow action bean needs AOP Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • WebFlow action bean needs AOP

    In my Project i use Spring WebFlow.
    I have a bean defined in one of my flow.xml files

    Code:
    <bean id="customerActions" class="com.system.actions.CustomerAction" >
    		<property name="webService" ref="customerWebService"/>
    		 <property name="agentService" ref="agentClient"/>  
    	</bean>
    Customer Action extends MultiAction class from webflow.

    Now i have a SecurityAspect class annotiated as AspectJ
    Code:
    @Aspect
    public class SecurityAspect {		
    	private SecuritySession session;
    	
    	@Before("@annotation(com.system.lib.Security)")
    	public void checkSecurity(JoinPoint jp) throws Throwable{
    		String userid = session.getUserid();
            if (userid == null) {          
                throw new SecurityException("User credentials must be present before attempting to invoke the method: "+ getMethod(jp).getName() );
            }   
            
    		
    	}
    }
    My CustomerAction contains annotation that should be intercepted by this SecurityAspect.
    However that is not the case, the aspect is never executed.


    I don't understand why this bean is omitted, it is spring managed.
    Is it possible that webflow has its own spring managed context and my SecurityAspect lives in a separate managed context?

    If someone has an opinion or knowledge on this please share.

  • #2
    With Spring AOP you can only execute external method calls. Spring Web Flow Actions have only 1 method which is externally called namly the execute methods. All other method calls are internal calls and aren't going to be proxied or executed.

    Comment


    • #3
      external method calls

      here is the CustomerAction
      I have a public method called setup
      Code:
      public class CustomerAction extends MultiAction{		
      	
      	@Security(group="POLCUSTOMER" )
      	public Event setup( RequestContext context ){
      		Customer c = ((Customer)context.getConversationScope().get("customer") );
      		CustomerRenderer renderer = new CustomerRenderer();		
      		renderer.setCustomer(c);
      		if( c != null ){
      			renderer.setBusinessVisible( c.getNameType().getValue().equals("I") == false );
      		}
      		// help generate a Command button for transision
      		String command = ((String)context.getFlashScope().get("commandFlow") );
      		renderer.setFlowCommand(command);		
      		context.getConversationScope().put("customerRenderer", renderer);
      		
      		
      		
      		return success();
      	}
      I have a create-customer-flow.xml
      that invokes this public method

      Code:
      	 
      	<start-actions>		
      		<action method="setup" bean="customerActions" />
      		<action method="getCustomerType" bean="customerActions" />	
      		<action method="getStateList" bean="customerActions" />	
      		<action method="getTitleList" bean="customerActions"/>
      		<action method="getSuffixList" bean="customerActions"/>
      	</start-actions>
      	
      	
      
      	<start-state idref="displayForm" />

      So i have to realize that all these methods cannot be intercepted by Spring AOP Aspects?

      Comment


      • #4
        I have a create-customer-flow.xml that invokes this public method
        It still calls the execute method, however the MultiAction uses some reflection to invoke the configured method on itself, effectivly making it an internal call.

        So i have to realize that all these methods cannot be intercepted by Spring AOP Aspects?
        Not with the proxy based approach. If you want to intercept those calls you will need a full AOP solution (like AspectJ) and use either load- or compile time weaving.

        Comment


        • #5
          Thank you

          thank you mdeinum for the swift clarification.

          I understand now.

          Comment


          • #6
            Webflow AspectJ PointCut

            You say use AspectJ because it uses compile-time weaving...

            I'm trying @AspectJ with java 5 annot. and
            just trying to get it working.

            I've added the configs:
            Code:
            <?xml version="1.0" encoding="UTF-8"?>
            <beans xmlns="http://www.springframework.org/schema/beans"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns:aop="http://www.springframework.org/schema/aop"
                   xsi:schemaLocation="
                       http://www.springframework.org/schema/beans
                       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                       http://www.springframework.org/schema/aop
                       http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
            
            
                <aop:aspectj-autoproxy>
                   <aop:include name="errorLogger" />
                </aop:aspectj-autoproxy>
            
                <bean id="errorLogger" class="org.springframework.webflow.samples.util.ErrorLogger" />
            </beans>
            ErrorLogger has the following
            Code:
            @Aspect
            public class ErrorLogger implements Serializable {
            
                @Pointcut("execution(* org.springframework.webflow.samples.util.SearchCriteria.*(..))")
                public void say(){}
            
                @Before("say()")
                public void sayHi(){
                    System.out.println("sayHi()");
                }
            }
            org.springframework.webflow.samples.util.SearchCri teria has method
            Code:
            public void throwExcept(){
                    System.out.println("throwExcept()");
                    try{
                        //int error = 2/0;
                        System.out.println("Annie are u OK?");
                    }
                    catch(Exception e){
                       System.out.println("throwExcept()"+e.getMessage());
                       e.printStackTrace();
                      //throw new Exception(e);
                    }
                 }
            to trigger the aspect in the flow...
            Code:
            <var name="searchCriteria" class="org.springframework.webflow.samples.util.SearchCriteria" />
            
                    <on-start>
                        <evaluate expression="searchCriteria.throwExcept()" />
                    </on-start>

            when this runs I get
            Code:
            2009-11-28 17:14:38,031 DEBUG [org.springframework.webflow.execution.AnnotatedAction] - <Putting action execution attributes map[[empty]]>
            throwExcept()
            Annie are u OK?
            so the aspect doesn't get triggered.

            However if I change the pointcut to..
            Code:
            @Before("execution(public * *(..))")
            the aspect does get triggered and I get "sayHi" everywhere
            eventually crashing the API.

            So what gives? why doesn't
            Code:
            @Pointcut("execution(* org.springframework.webflow.samples.util.SearchCriteria.*(..))")
            This work? I've tried many variations but no way of selecting my method ( as a test run).

            Is Webflow complicating the way Spring AOP normally works?

            Comment


            • #7
              You say use AspectJ because it uses compile-time weaving...

              I'm trying @AspectJ with java 5 annot. and
              just trying to get it working.
              First of all you aren't using loadtime or compile time weaving, you are still using spring aop, which is proxy based.

              Next each flow xml results in a BeanFactory/ApplicationContext itself. Spring AOP only works on beans defined in the same applicationcontext. Spring AOP (when it kicks in) doesn't know about your SearchCriteria bean and will never know about your SearchCriteria bean because it is local to the flow and not the applicationcontext the aop stuff is defined in.

              Comment


              • #8
                Webflow Aspectj

                Hi Marten,

                Thanks for your help and interest in this matter!

                OK so I tried Load-Time Weaving (LTW) as you advised ...

                I placed the aop.xml where my persistence.xml resides ( I'm hoping this gets recognized because of the errors I get)

                Code:
                <!DOCTYPE aspectj PUBLIC
                        "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
                <aspectj>
                    <weaver>
                        <!-- only weave classes in this package will include subpkgs -->
                        <include within="org.springframework.webflow.samples..*"/>
                    </weaver>
                    <aspects>
                        <!-- use only this aspect for weaving -->
                        <!-- <aspect name="org.springbyexample.aspectjLoadTimeWeaving.PerformanceAdvice" /> -->
                        <aspect name="org.springframework.webflow.samples.util.ErrorLogger" />
                    </aspects>
                </aspectj>
                In my main config I am trying to find what to put as weaver class?
                Code:
                <context:load-time-weaver  aspectj-weaving="on"  weaver-class="???"  />
                If nothing then ..
                Code:
                java.io.NotSerializableException: org.springframework.context.weaving.DefaultContextLoadTimeWeaver
                If I place the class (from spring-agent.jar) in the server and set the javaagent ../libs/Spring-agent.jar in the
                catalina.bat of Tomcat so that it starts
                Code:
                if not exist "%CATALINA_BASE%\conf\logging.properties" goto noJuli
                set JAVA_OPTS=%JAVA_OPTS% -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file="%CATALINA_BASE%\conf\logging.properties -javaagent:../server/lib/spring-agent.jar"
                then it too is not serialized. So I then added "implements Serialization" to the class jar it put it in play,
                and get..
                Code:
                java.io.NotSerializableException: org.apache.catalina.loader.WebappClassLoader
                and so on with no hope of serializing the chain of implyed classes
                ( for this reason I feel I am on the wrong track...)

                Must I write some kind of Custom LoadTimeWeaving class and how could you do this?
                I saw the following config at http://www.springbyexample.org/examp...pectj-ltw.html
                but was unable to see/checkout the sc
                Code:
                <?xml version="1.0" encoding="UTF-8"?>
                <beans xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:context="http://www.springframework.org/schema/context"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans 
                                        http://www.springframework.org/schema/beans/spring-beans.xsd
                                        http://www.springframework.org/schema/context 
                                        http://www.springframework.org/schema/context/spring-context.xsd">
                
                    <context:load-time-weaver />
                    
                    <bean id="processor" class="org.springbyexample.aspectjLoadTimeWeaving.Processor" />
                    
                </beans>
                In short, just how does one config and implement aspectj (LTW) for Webflow??
                I don't see anything out there really, is it possible?
                Webflow requires serialization for snapshots etc,...

                I just know there's something I'm missing/overlooked!

                Can anyone stear/help me in the right direction?

                There's just nothing on AOP for webflow in the manual or forums!



                Hope to hear from someone,

                Best Regards,

                John.

                Comment


                • #9
                  Hi John,

                  I used the documentation at following link and got it working smoothly.

                  http://static.springsource.org/sprin...#aop-ataspectj
                  Look the example in section

                  8.8.4 Load-time weaving with AspectJ in the Spring Framework

                  Cheers.
                  Deepak
                  Last edited by cbawad; Mar 7th, 2012, 03:32 AM.

                  Comment

                  Working...
                  X