简体   繁体   中英

Spring AOP expression throw java.lang.IllegalArgumentException: warning no match for this type name […]

I'm new to Spring AOP and I'm quite disturbed...

I run JBoss 7.2, Mojara 2.2.2 and Spring 3.1.2.RELEASE.

I have the following dispatcher-servlet.xml

<mvc:annotation-driven />
<context:annotation-config />
<aop:aspectj-autoproxy  proxy-target-class="true" />
<context:component-scan base-package="com.project.scheduler" />
<task:annotation-driven scheduler="taskScheduler" />
<task:scheduler id="taskScheduler" pool-size="2" />

Here is my aspect:

@Aspect
@Component
public class BatchHistorizerAspect implements Serializable {

    private static final long  serialVersionUID = 2620746940572873202L;
    public static final Logger LOGGER           = LogManager.getLogger(BatchHistorizerAspect.class);

    @Around("execution(* com.project.scheduler.StatusCleanScheduler.schedule(..))")
    public void aroundSchedule(ProceedingJoinPoint jp) {
        LOGGER.debug("aroundSchedule start");
        try {
            jp.proceed();
        } catch (Throwable e) {
            LOGGER.debug("aroundSchedule exception:", e);
        }
        LOGGER.debug("aroundSchedule end");
    }
}

And finally the class I want to advice:

@Component
public class StatusCleanScheduler implements Serializable {

    private static final long       serialVersionUID = -8061115218184844863L;
    private final static Logger     LOGGER           = LogManager.getLogger(StatusCleanScheduler.class);

    @Autowired
    private StatusService statusService;

    @Override
    @Scheduled(cron = "0 * * * * *")
    public void schedule() {
        LOGGER.info("Start Status orphans cleaning");
        statusService.cleanOrphans();
        LOGGER.info("End Status orphans cleaning");
    }
}

When I start my server, it throws the following:

ERROR [ServerService Thread Pool -- 54] org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/agathe]: JBWEB000289: Servlet dispatcher threw load() exception: java.lang.IllegalArgumentException: warning no match for this type name: com.project.scheduler.StatusCleanScheduler [Xlint:invalidAbsoluteTypeName]
    at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301) [aspectjweaver-1.6.12.jar:1.6.12]
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:207) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.getFallbackPointcutExpression(AspectJExpressionPointcut.java:358) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.getShadowMatch(AspectJExpressionPointcut.java:409) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
...

But when I change the @Around to @Around("execution(* com.project.scheduler.*.schedule(..))") everything is OK and my aspect is correctly called.

What am I doing wrong?

UPDATE:

I have done a little workaround, but I find it quite dirty...

@Around("execution(* com.project.scheduler.*.schedule(..))")
public void aroundSchedule(ProceedingJoinPoint jp) {
    Object obj = jp.getThis();
    if (!(obj instanceof StatusCleanScheduler)) {
        jp.proceed();
        return;
    }
    StatusCleanScheduler batch = (StatusCleanScheduler) obj;
    LOGGER.debug("aroundSchedule start");
    try {
        jp.proceed();
    } catch (Throwable e) {
        LOGGER.debug("aroundSchedule exception:", e);
    }
    LOGGER.debug("aroundSchedule end");
}

If you have a better solution, please tell me.

As I said in my comment, the [Xlint:invalidAbsoluteTypeName] tells you that your real, fully qualified class name is different from the one you use in your pointcut. Compare the two and there you will find a mismatch which is easily fixed. Maybe it is just a typo.

If you want to code a little more defensively, use wildcards like this so you can move around your class into subpackages if you like:

Find class StatusCleanScheduler in any subpackage of com.project.scheduler (this is probably what you want):

execution(* com.project.scheduler..StatusCleanScheduler.schedule(..))

Just for reference, you can also do this:

Find class StatusCleanScheduler in any subpackage of com.project :

execution(* com.project..StatusCleanScheduler.schedule(..))

Find classes ending with Scheduler in any subpackage of com.project :

execution(* com.project..*Scheduler.schedule(..))

Find any schedule method within your project:

execution(* com.project..schedule(..))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM