Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: Aop in child-parent context relationship

  1. #1
    Join Date
    Mar 2007
    Location
    Poland
    Posts
    341

    Default Aop in child-parent context relationship

    I have a problems with my AOP configuration.

    I am having quite a big project on WAS 6.1.0.13, Spring 2.5.4.
    My projects is a EAR that consists of 2 WARS (web module and webservices module) and EJB module.

    I have a hierarchy of context :
    each of wars have its own context (specified in web.xml ) with module specific beans and there is a shared context with some back-end beans. Sharing of context is achieved by using locatorFactorySelector , and parentContextKey in both of web.xml files.



    Everything works great but i have a problem with configuring AOP in webservices module context.

    I am using namespace aop syntax approach to configure aspects.
    In my shared context i have
    Code:
    <tx:annotation-driven transaction-manager="transactionManager" order="200"/>
    
    <context:annotation-config />
    
    <bean id="timeMeasureinterceptor" class="pl.spring.interceptor.TimeMeasureInterceptor">
    		<property name="tier" value="tier"/>
    	</bean>
    
    	<bean id="modulesInterceptor" class="pl.spring.interceptor.ModulesInterceptor"/>
    
    	<aop:config  proxy-target-class="false">
    		<aop:advisor  advice-ref="timeMeasureinterceptor" order="1" pointcut="bean(*Validator) or bean(*Manager) or bean(*DAO)" />
    		<aop:advisor  advice-ref="modulesInterceptor" order="10" pointcut="bean(authorizationModule) or bean(administrationModule) or bean(informationModule)" />
    	</aop:config>
    Both TimeMeasureInterceptor and ModulesInterceptor implements org.aopalliance.intercept.MethodInterceptor interface.


    Everything works as expected.

    Next I added in my webservices module context the following line:
    Code:
    <bean id="requestContextBindingAspect" class="pl.ws.aspects.RequestContextBindingAspect"/>
    	<aop:config  proxy-target-class="false">
    		<aop:advisor  advice-ref="requestContextBindingAspect" order="1" pointcut="execution(* org.springframework.ws.server.endpoint.MessageEndpoint.*(..))" />
    	</aop:config>
    RequestContextBindingAspect is implementation of MethodInterceptor interface.

    I want to intercept all calls on MessageEndpoint implementations (just one method invoke() ) but what i see in my logs looks very weird.

    ModulesInterceptor defined above, that should only intercept method calls of beans with names: administrationModule , authorizationModule, informationModule, is fired on execution of any method of each bean defined in my webservices context => all internal spring webservices beans ( impliciltly created by Spring WebServices) and my own defined beans are wrapped by ModulesInterceptor.

    My own beans are also wrapped by requestContextBindingAspect (which is what i expect).

    I decided to make 2 tests:
    1) Remove modulesInterceptor along with its advisor => everything works as expected (only requestContextBindingAspect in proper pointcuts is fired)

    There is 1 funny thing in this test : timeMeasureinterceptor which is defined in similar fashion like modulesInterceptor does not intercept beans in webservices context.

    2) Remove requestContextBindingAspect => now beans defined in webservices modules are not intercepted by anything (modulesInterceptor does not intercept any calls except for these on beans with names authorizationModule or administrationModule or informationModule)

    Can anyone explain me what is going on??

    Why child context beans are somehow autoproxied by one of the interceptors (and just one - modulesInterceptor ) defined in parent context?

  2. #2
    Join Date
    Mar 2007
    Location
    Poland
    Posts
    341

    Default

    I am working on a case but still no results.
    The one thing to mention is, if i change my shared context:
    Code:
    <aop:config  proxy-target-class="false">
    		<aop:aspect ref="timeMeasureinterceptor" order="1">
    			<aop:around method="doBasicProfiling" pointcut="bean(*Validator) or bean(*Manager) or bean(*DAO)"/>
    		</aop:aspect>		
    </aop:config>
    <aop:config  proxy-target-class="false">
    		<aop:pointcut id="moduleInvocations" expression="bean(authorizationModule) or bean(administrationModule) or bean(informationModule)"/>
    		<aop:advisor  advice-ref="modulesInterceptor" order="10" pointcut-ref="moduleInvocations" />
    </aop:config>
    So this time i have 2 <aop:config> elements with <aop:aspect> instead of single <aop:config> config with 2 aop:advisor , all beans from webservices module context are now intercepted by timeMeasureinterceptor !


    It means the problem does not lie in pointcut "moduleInvocations".

    Maybe this fact can help anyone to find out what is going on and how to explain the case.

  3. #3
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    Maybe this fact can help anyone to find out what is going on and how to explain the case.
    There is to much missing to pin point your issue here.

    How have you defined your parent/child contexts? How do you load your application contexts? Where are your spring.jar files? Only in the ear or only in the wars or both?

    You don't use any import statement in the applicationContext files from your web application?
    Last edited by Marten Deinum; Aug 31st, 2008 at 03:48 AM.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  4. #4
    Join Date
    Mar 2007
    Location
    Poland
    Posts
    341

    Default

    Quote Originally Posted by Marten Deinum View Post
    There is to much missing to pin point your issue here.

    How have you defined your parent/child contexts? How do you load your application contexts? Where are your spring.jar files? Only in the ear or only in the wars or both?

    You don't use any import statement in the applicationContext files from your web application?
    Hi Marten

    Thanks for answering.

    I know, there are a lot of missing points where something could go wrong.
    The application as i wrote above is quite big and consists of EJB project (nowadays we do not have EJBs and all services beans are just simple POJO),
    2 web projects - web module based on Struts2 and the second is webservices module that utilize Spring Web Services project, and in the end several of utility jars referenced by EJB or/and WEB modules

    Each of the web modules loads its own context(which is built from several files) and there is a single shared context which is a parent context of web modules contexts.
    It is all configured in a way how Joris Kuipers described in his blog.

    I am not able to access source code from CVS right now but i will paste my configuration as soon as i get home. I am quite sure that context loading looks ok cause there is only single instance of each bean in shared context - bean defined in shared context has the same reference (address) when chcecking in web module and webservices module.

    Spring jars are located right under EAR and are referenced by each of the projects by entries in MANIFEST.MF file.

    Spring Web Services jars are located in WEB-INF/lib folder in web services module.

    As i wrote above i do not have access to source code of the project now but I do not think it can be a problem with import statements in applicationContext files because of the case i presented in previous message:
    If i just refactored AOP definition - change from 2 <aop:advisor> elements to single <aop:advisor> and one <aop:aspect> element , all beans defined in web services module are now intercepted by interceptor associated with <aop:aspect> not by the interceptor associated with 2nd <aop:advisor> as it was before !

    I will check my configuration again as soon as i come back home, and paste my configuration files.
    But still thinkg of what is going on ...

  5. #5
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    The problem is that an aop:advisor/aspect defined in the parent doesn't do anything in the child context, and the same goes the other way around. Anything defined in the child context works only on beans in that context not on the parent.

    the aop:config stuff is only applied in the ApplicationContext they are loaded in.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  6. #6
    Join Date
    Mar 2007
    Location
    Poland
    Posts
    341

    Post

    I finally have some time to send my configuration and packaging.
    ear:
    web.war
    web-ws.war
    service.jar
    util-dao.jar
    util-platform.jar
    util-messages.jar
    util-security.jar
    websphere-env-context.jar
    ...
    hibernate, spring,jdbc,log4j, commons jars

    web.xml from module "web"
    Code:
    <context-param>
    		<param-name>contextConfigLocation</param-name>
    		<param-value>
    			/WEB-INF/strutsContext.xml, classpath:/messages-context.xml,
    			classpath:/validators-context.xml
    		</param-value>
    	</context-param>
    	<context-param>
    		<param-name>locatorFactorySelector</param-name>
    		<param-value>
    			classpath*:pl/web/context/*-env-context.xml
    		</param-value>
    	</context-param>
    	<context-param>
    		<param-name>parentContextKey</param-name>
    		<param-value>servicesContext</param-value>
    	</context-param>
    web.xml of module "web-ws"
    Code:
    <context-param>
    		<param-name>contextConfigLocation</param-name>
    		<param-value>
    			classpath:/applicationContext-ws.xml,
    			classpath:/validators-context.xml
    		</param-value>
    	</context-param>	
    	<context-param>
            <param-name>locatorFactorySelector</param-name>
            <param-value>classpath*:pl/web/context/*-env-context.xml</param-value>
        </context-param>
    	<context-param>
            <param-name>parentContextKey</param-name>
            <param-value>servicesContext</param-value>
        </context-param>
    <servlet>
    		<display-name>
    		sss</display-name>
    		<servlet-name>spring-ws</servlet-name>
    		<servlet-class>
    			org.springframework.ws.transport.http.MessageDispatcherServlet
    		</servlet-class>
    		<init-param>
    			<param-name>transformWsdlLocations</param-name>
    			<param-value>true</param-value>			
    		</init-param>
    	</servlet>
    	<listener>
    		<listener-class>
    			org.springframework.web.context.ContextLoaderListener
    		</listener-class>
    	</listener>
    
    	<servlet-mapping>
    		<servlet-name>spring-ws</servlet-name>
    		<url-pattern>/*</url-pattern>
    	</servlet-mapping>
    locatorFactorySelector points to file pl/web/context/websphere-env-context.xml which is inside websphere-env-context.jar
    The source of websphere-env-context.xml
    Code:
    <bean id="servicesContext" class="org.springframework.context.support.ClassPathXmlApplicationContext">
            <constructor-arg>
                <list>
                    <value type="java.lang.String">service-context.xml</value>
                    <value type="java.lang.String">util-dao-context.xml</value>
                    <value type="java.lang.String">websphere-util-dao-context.xml</value>
    <value type="java.lang.String">util-security-context.xml</value>
                </list>
            </constructor-arg>
        </bean>

    The source of service-context
    Code:
    	<!-- enable the configuration of transactional behavior based on annotations -->
    	<tx:annotation-driven transaction-manager="transactionManager" order="200"/>
    	<!-- <aop:aspectj-autoproxy/> -->
    
    	<context:annotation-config />
    
    	<bean id="timeMeasureinterceptor" class="pl.spring.interceptor.TimeMeasureInterceptor">
    		<property name="tier" value="tier"/>
    	</bean>
    
    	<bean id="modulesInterceptor" class="pl.spring.interceptor.ModulesInterceptor"/>
    
    	<aop:config  proxy-target-class="false">
    		<aop:aspect ref="timeMeasureinterceptor" order="1">
    			<aop:around method="doBasicProfiling" pointcut="bean(*Validator) or bean(*Manager) or bean(*DAO)"/>
    		</aop:aspect>		
    	</aop:config>
    
    	<aop:config  proxy-target-class="false">
    		<aop:pointcut id="modulesInterceptor" expression="bean(authorizationModule) or bean(administrationModule) or bean(informationModule)"/>
    		<aop:advisor  advice-ref="dracoModulesInterceptor" order="10" pointcut-ref="dracoModuleInvocations" />
    	</aop:config>
    
    ...	
    bussiness beans
    </beans>
    util-dao-context.xml consist of definition of HibernateTransactionManager and daos. It does not define any aop beans nor aop elements.

    validators-context.xml define only validator (our custom validation ) beans, each of the validator bean is prototype. no aop configuration

    websphere-util-dao-context.xml - websphere datasource and websphere specific lob handler, no aop configuration


    util-security-context.xml :
    Code:
    <bean id="authorizationModule" class="pl.stub.AuthorizationModuleStub"/>
    	<bean id="administrationModule" class="pl.stub.AdministrationModuleStub"/>
    	<bean id="informationModule" class="pl.stub.InformationModuleStub"/>
    	
    	<bean id="privilegesInterceptor" class="pl.spring.interceptor.PrivilegesInterceptor"/>
    	
    	<aop:config  proxy-target-class="false">
    		<aop:advisor advice-ref="privilegesInterceptor" pointcut="execution(* pl.api.information.InformationModule.getUserPrivileges(..))"/>
    	</aop:config>
    As provided above web module has web context that consists of 3 files: strutsContext.xml, messages-context.xml, validators-context.xml.

    Strutscontext.xml contains beans that act as Struts2 actions and has no aop configuration.

    messages-context.xml defines single bean of type org.springframework.context.support.ResourceBundle MessageSource

    validators - described above.


    Web-ws module has 2 contexts: one defined by a file with the same name as servlet that handles web services requests calls, and the second that consists of 2 files: applicationContext-ws.xml, validators-context.xml.

    spring-ws.xml;
    Code:
    <bean id="wsd" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
            <property name="schemaCollection" ref="schemaCollection"/>
            <property name="portTypeName" value="port"/>
            <property name="locationUri" value="http://localhost:9080/web-ws/services"/>
            <property name="targetNamespace" value="http://www.foo.bar.pl/spring-ws/schemas/messages"/>
        </bean>
    validators-context - was described above (i know i could load validators-context.xml in shared context)

    applicationContext-ws.xml:
    Code:
    <context:annotation-config/>
    	<bean id="messageFactory"
    	class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
    		<constructor-arg>
    			<bean
    				class="com.ibm.ws.webservices.engine.soap.MessageFactoryImpl" />
    		</constructor-arg>
    	</bean>
    
    	<oxm:jaxb2-marshaller id="marshaller"
    		contextPath="pl.ivmx.dol.ws.schema" />
    		
    	<bean id="requestContextBindingAspect" class="pl.ws.aspects.RequestContextBindingAspect"/>
    
    	 <aop:config  proxy-target-class="false">
    		<aop:advisor  advice-ref="requestContextBindingAspect" order="1" pointcut="execution(* org.springframework.ws.server.endpoint.MessageEndpoint.*(..))" />
    	</aop:config>
    
    	<bean id="schemaCollection"		class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection"
    		lazy-init="true">
    		<description>
    		<property name="xsds" value="/messages.xsd" />
    		<property name="inline" value="true" />
    	</bean>
    ...
    endpoints definition
    Using the configuration i provided above all beans defined in applicationContext-ws.xml are intercepted by timeMeasureinterceptor.
    If i added test.xml file:
    Code:
    <bean id="testKlasa" class="pl.ws.util.TestKlasa"/>
    And add it to webservices module web.xml file, "testKlasa" bean is also wrapped in timeMeasureInterceptor proxy.

    Marten, Can you explain me why all this happens...

  7. #7
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    You have a lot of nesting going on, needed to do some drawing.

    Code:
    Marten, Can you explain me why all this happens...
    If everything was configured correctly this should not happen. The bean will only be wrapped by the timeMeasureInterceptor if that interceptor is part of the current context. (Hence my import resource suspicion).

    Or at least it looks like something is happening what cases the contexts to be merged.

    Is it possible to create an ear/maven project which reproduces this, so that I can test?
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  8. #8
    Join Date
    Mar 2007
    Location
    Poland
    Posts
    341

    Default

    Quote Originally Posted by Marten Deinum View Post
    You have a lot of nesting going on, needed to do some drawing.

    Code:
    Marten, Can you explain me why all this happens...
    If everything was configured correctly this should not happen. The bean will only be wrapped by the timeMeasureInterceptor if that interceptor is part of the current context. (Hence my import resource suspicion).

    Or at least it looks like something is happening what cases the contexts to be merged.

    Is it possible to create an ear/maven project which reproduces this, so that I can test?
    Hi

    I will do my best tommorow to provide minimal ear to reproduce the issue.
    Thanks a lot

  9. #9
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    Thanks. I don't have a WebSphere instance here, so I hope I can see it from the ears or hopefully JBoss or GlassFish has the same issue.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  10. #10
    Join Date
    Mar 2007
    Location
    Poland
    Posts
    341

    Default

    Hi Matren,

    Finally had enough energy (I am sick an lying in a bed) to prepare ear to reproduce the issue.

    Sorry but had no time to write ant/maven script to assemble project and i just prepared everything in MyEclipse.

    Websphere 6.1.0.13 compatible ear

    Here you have a zip that contains all projects zipped
    http://www.man.poznan.pl/~milus/aopProblem.zip

    As i wrote above all these are just eclipse(MyEclipse) project - i only removed thirdParty jars (for example spring jars) from aopTest to make file smaller.

    If you would like to recreate projects just copy third party jars located just under ear to aopTest project.

    i also put short description

    If you need more details or anything that can help you in building/assembling/deploying my application pls send me an email.

    Do you want me to share my webservices client application ?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •