spring-aop not working due to Failed to create fallback PointcutExpression

40 Views Asked by At

Aspect

package dim.aop;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {
    
    private final Logger LOG = Logger.getLogger(this.getClass());
    
    @Before("execution(* dim.service.QuartzServiceImpl.*(..))")
    public void before(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().toShortString();
        LOG.error(methodName + " Start");
    }
}

service

package dim.service;

import javax.annotation.PostConstruct;
import org.springframework.stereotype.Service;

@Service
public class QuartzServiceImpl implements QuartzService {
    
    @PostConstruct
    void initJobs() {
        
    }
}

applicationContext.xml

<aop:aspectj-autoproxy expose-proxy="true" />

log

    44: 2023-12-28 17:12:24,607 DEBUG [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] - Identified candidate component class: VFS resource ["/D:/app/codereadystudio/runtimes/jboss-eap-7.4/standalone/deployments/EmsApp.war/WEB-INF/classes/dim/aop/LoggingAspect.class"]
    57: 2023-12-28 17:12:25,124 DEBUG [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] - Identified candidate component class: VFS resource ["/D:/app/codereadystudio/runtimes/jboss-eap-7.4/standalone/deployments/EmsApp.war/WEB-INF/classes/dim/service/QuartzServiceImpl.class"]
    79: 2023-12-28 17:12:28,248 DEBUG [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] - Identified candidate component class: VFS resource ["/D:/app/codereadystudio/runtimes/jboss-eap-7.4/standalone/deployments/EmsApp.war/WEB-INF/classes/dim/aop/LoggingAspect.class"]
    91: 2023-12-28 17:12:28,726 DEBUG [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] - Identified candidate component class: VFS resource ["/D:/app/codereadystudio/runtimes/jboss-eap-7.4/standalone/deployments/EmsApp.war/WEB-INF/classes/dim/service/QuartzServiceImpl.class"]

   663: 2023-12-28 17:12:31,444 DEBUG [org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory] - Found AspectJ method: public void dim.aop.LoggingAspect.before(org.aspectj.lang.JoinPoint)

  2550  2023-12-28 17:12:32,203 DEBUG [org.springframework.aop.aspectj.AspectJExpressionPointcut] - Failed to create fallback PointcutExpression
  2551: java.lang.IllegalArgumentException: warning no match for this type name: dim.service.QuartzServiceImpl [Xlint:invalidAbsoluteTypeName]
  2552      at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301)

  4975: 2023-12-28 17:12:49,035 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Creating shared instance of singleton bean 'loggingAspect'
  4976: 2023-12-28 17:12:49,035 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Creating instance of bean 'loggingAspect'
  4977: 2023-12-28 17:12:49,036 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Eagerly caching bean 'loggingAspect' to allow for resolving potential circular references
  4978: 2023-12-28 17:12:49,038 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Finished creating instance of bean 'loggingAspect'

  6556: 2023-12-28 17:12:51,144 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Creating shared instance of singleton bean 'quartzServiceImpl'
  6557: 2023-12-28 17:12:51,144 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Creating instance of bean 'quartzServiceImpl'
  6560: 2023-12-28 17:12:51,150 DEBUG [org.springframework.context.annotation.CommonAnnotationBeanPostProcessor] - Found init method on class [dim.service.QuartzServiceImpl]: void dim.service.QuartzServiceImpl.initJobs()
  6561: 2023-12-28 17:12:51,151 DEBUG [org.springframework.context.annotation.CommonAnnotationBeanPostProcessor] - Registered init method on class [dim.service.QuartzServiceImpl]: org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement@ffbad86
  6562: 2023-12-28 17:12:51,151 DEBUG [org.springframework.beans.factory.annotation.InjectionMetadata] - Registered injected element on class [dim.service.QuartzServiceImpl]: AutowiredFieldElement for private org.quartz.Scheduler dim.service.QuartzServiceImpl.scheduler
  6563: 2023-12-28 17:12:51,151 DEBUG [org.springframework.beans.factory.annotation.InjectionMetadata] - Registered injected element on class [dim.service.QuartzServiceImpl]: AutowiredFieldElement for private dim.service.SystemService dim.service.QuartzServiceImpl.systemService
  6564: 2023-12-28 17:12:51,152 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Eagerly caching bean 'quartzServiceImpl' to allow for resolving potential circular references
  6565: 2023-12-28 17:12:51,155 DEBUG [org.springframework.beans.factory.annotation.InjectionMetadata] - Processing injected element of bean 'quartzServiceImpl': AutowiredFieldElement for private org.quartz.Scheduler dim.service.QuartzServiceImpl.scheduler

  6612: 2023-12-28 17:12:51,304 DEBUG [org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor] - Autowiring by type from bean name 'quartzServiceImpl' to bean named 'schedulerFactoryBean'
  6613: 2023-12-28 17:12:51,304 DEBUG [org.springframework.beans.factory.annotation.InjectionMetadata] - Processing injected element of bean 'quartzServiceImpl': AutowiredFieldElement for private dim.service.SystemService dim.service.QuartzServiceImpl.systemService
  6615: 2023-12-28 17:12:51,305 DEBUG [org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor] - Autowiring by type from bean name 'quartzServiceImpl' to bean named 'systemServiceImpl'
  6616: 2023-12-28 17:12:51,305 DEBUG [org.springframework.context.annotation.CommonAnnotationBeanPostProcessor] - Invoking init method on bean 'quartzServiceImpl': void dim.service.QuartzServiceImpl.initJobs()

  6640: 2023-12-28 17:12:52,462 DEBUG [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator] - Creating implicit proxy for bean 'quartzServiceImpl' with 0 common interceptors and 3 specific interceptors
  6641: 2023-12-28 17:12:52,462 DEBUG [org.springframework.aop.framework.JdkDynamicAopProxy] - Creating JDK dynamic proxy: target source is SingletonTargetSource for target object [dim.service.QuartzServiceImpl@51161910]
  6642: 2023-12-28 17:12:52,465 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Finished creating instance of bean 'quartzServiceImpl'

My service works fine and I want to add a aspect. Spring registered both aspect and service. However the AOP does not work as expected. I checked the pointcut expression, it is correct. The package and class name are correct too. But I still get invalidAbsoluteTypeName error. If I change the expression to this execution(* dim.service.QuartzServiceImpl..*(..)) , the error message disappeared but AOP still not functioning.

1

There are 1 best solutions below

0
kriegaex On

Did you notice this in the log (adding line breaks for readability)?

Creating JDK dynamic proxy:
  target source is SingletonTargetSource
  for target object [dim.service.QuartzServiceImpl@51161910]

You are using Spring's default proxy mode, i.e. if your class implements an interface, Spring will create a JDK proxy implementing all interfaces the class also implements, but extend those interfaces, not the *Impl class itself. I.e. in this case, the proxy is not a subclass of QuartzServiceImpl but of QuartzService, the proxy only passes on calls to its QuartzServiceImpl delegate.

This explains why your pointcut will not match. Simply change it to execution(* dim.service.QuartzService.*(..)) or within(dim.service.QuartzService).

It is also possible to change the proxy mode to directly extend classes, even if they implement interfaces (using CGLIB proxies instead of JDK ones), but actually it is a much cleaner approach to program against interfaces than against specific implementations.