Results 1 to 3 of 3

Thread: IllegalArgumentException when referencing another pointcut

  1. #1
    Join Date
    Aug 2006
    Posts
    8

    Default IllegalArgumentException when referencing another pointcut

    I get an IllegalArgumentException when I reference a pointcut from another pointcut within the same <aop:config> element. I'm using the nightly build spring-framework-2.0-rc4-with-dependencies-build.1-20060830.zip.

    My config file is as follows:

    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"
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    	<bean id="serviceBean" class="com.s1.arch.test.FakeConcreteService" />
    
    	<tx:advice id="serviceTxAdvice">
    		<tx:attributes>
    			<tx:method name="*" propagation="REQUIRED" />
    		</tx:attributes>
    	</tx:advice>
    	
    	<aop:config>
    		<aop:pointcut id="allServiceOperations"
    			expression="execution(public * com.s1..*Service.*(..))" />
    		<aop:pointcut id="txServiceOperations"
    			expression="allServiceOperations()" />
    		<aop:advisor advice-ref="serviceTxAdvice"
    			pointcut-ref="txServiceOperations" />
    	</aop:config>
    
    	<bean id="transactionManager"
    		class="com.s1.arch.test.FakeSpringTransactionManager">
    	</bean>
    </beans>
    and I'm getting the exception as the application context is created by the following JUnit test case:
    Code:
    public class SpringThreadTest extends TestCase {
        public void testForSpringThread() {
            FakeSpringTransactionManager.reset();
            BeanFactory beanFactory = new ClassPathXmlApplicationContext(
                    "spring-config//test-springthread.xml");
        }
    }
    The exception's stack trace is:
    Code:
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serviceBean' defined in class path resource [spring-config//test-springthread.xml]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut allServiceOperations
    Caused by: java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut allServiceOperations
    	at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:315)
    	at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:172)
    	at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:162)
    	at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:103)
    	at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:190)
    	at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:250)
    	at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:275)
    	at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:68)
    	at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:54)
    	at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:247)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:301)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:933)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:415)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:242)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:141)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:239)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:155)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:300)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:346)
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:92)
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:77)
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:68)
    	at org.grnds.facility.factory.spring.SpringThreadTest.testForSpringThread(SpringThreadTest.java:18)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:85)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:58)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:60)
    	at java.lang.reflect.Method.invoke(Method.java:391)
    	at junit.framework.TestCase.runTest(TestCase.java:154)
    	at junit.framework.TestCase.runBare(TestCase.java:127)
    	at junit.framework.TestResult$1.protect(TestResult.java:106)
    	at junit.framework.TestResult.runProtected(TestResult.java:124)
    	at junit.framework.TestResult.run(TestResult.java:109)
    	at junit.framework.TestCase.run(TestCase.java:118)
    	at junit.framework.TestSuite.runTest(TestSuite.java:208)
    	at junit.framework.TestSuite.run(TestSuite.java:203)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:436)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:311)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
    This is obviously a simplified test case to isolate the problem - what I really want to do is to combine named pointcuts, but kept running into errors so cut it down to as little as possible. Should this work? Is it a bug or am I doing something wrong?

    Assuming it should work, I have another follow-on question: if you want to combine pointcuts in xml configuration must they all belong to the same <aop:config> element? Is there a way that 2 pointcuts from separate configuration files can be combined?

    Thanks!

    Barbara

  2. #2
    Join Date
    Jun 2006
    Location
    SF Bay Area, California
    Posts
    524

    Default Aliasing or referring to other pointcuts doesn't work in XML

    You are facing limitations of pointcuts defined using XML, where pointcut expressions may not contain references to other pointcuts. The error message could be improved to point to txServiceOperations' expression. Please file a JIRA issue so that a future version may consider providing a better error message.

    If you modify your XML as follows:
    Code:
    <aop:config>
    	<aop:pointcut id="allServiceOperations"
    		expression="execution(public * test.Foo.*(..))" />
    	<aop:pointcut id="txServiceOperations"
    		expression="allServiceOperations()" />
    	<aop:advisor advice-ref="serviceTxAdvice"
    		pointcut-ref="allServiceOperations" />
    </aop:config>
    or
    Code:
    <aop:config>
    	<aop:pointcut id="allServiceOperations"
    		expression="execution(public * test.Foo.*(..))" />
    	<aop:pointcut id="txServiceOperations"
    		expression="execution(public * test.Foo.*(..))" />
    	<aop:advisor advice-ref="serviceTxAdvice"
    		pointcut-ref="allServiceOperations" />
    	</aop:config>
    Everything should work well.

    You may want to consider using @AspectJ-styled aspects (if you are using Java 5.x). You don't have these limitations over there.

    -Ramnivas
    Ramnivas Laddad (Follow me on Twitter)
    AspectJ in Action: Enterprise AOP with Spring Applications (2nd edition). Now available!

  3. #3
    Join Date
    Aug 2006
    Posts
    8

    Default Thanks - how about AbstractTransactionAspect?

    Hi Ramnivas,

    Thanks! I pored over the documentation before posting but somehow managed to miss the statement "it is not possible to combine named pointcuts declared in XML" - ho hum.

    Unfortunately, we're limited to JDK1.4 so @AspectJ style is not possible for us.

    I'm replacing our EJB services with POJO services with spring transactions - I'd have liked to use declarative transactions, but we work in an environment where we deliver through 4 development teams before hitting the customer. So I need to find a way downstream teams can re-use pointcut definitions to add their own services or modify transaction types of existing services, preferably without redefining everything from scratch.

    Is the only route open to me to define my pointcuts using AbstractTransactionAspect? How will this work without annotations? Is there an example somewhere I can refer to?

    Thanks again,

    Barbara

Posting Permissions

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