Announcement Announcement Module
Collapse
No announcement yet.
IllegalArgumentException when referencing another pointcut Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    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

    Comment


    • #3
      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

      Comment

      Working...
      X