spring aop报Mismatch on arguments to advice method错误问题
来源:互联网 发布:linux 查找文件夹大小 编辑:程序博客网 时间:2024/05/21 23:49
在项目中用到spring的aop功能,总昨天开始发现每次执行apo的pointcut的时候,都会报这样的错误:
org.springframework.aop.AopInvocationException: Mismatch on arguments to advice method [public void com.service.impl.LogServiceImpl.logArg(org.aspectj.lang.JoinPoint)]; pointcut expression [org.aspectj.weaver.internal.tools.PointcutExpressionImpl@95215b]; nested exception is java.lang.IllegalArgumentException: object is not an instance of declaring classCaused by: java.lang.IllegalArgumentException: object is not an instance of declaring classat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)at java.lang.reflect.Method.invoke(Method.java:597)at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:597)at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:576)at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:45)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)at $Proxy6.createPlanTaskTemplete(Unknown Source)at service.TestPlanTask.testCreatePlanTaskTemplete(TestPlanTask.java:31)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)at java.lang.reflect.Method.invoke(Method.java:597)at junit.framework.TestCase.runTest(TestCase.java:168)at junit.framework.TestCase.runBare(TestCase.java:134)at junit.framework.TestResult$1.protect(TestResult.java:110)at junit.framework.TestResult.runProtected(TestResult.java:128)at junit.framework.TestResult.run(TestResult.java:113)at junit.framework.TestCase.run(TestCase.java:124)at junit.framework.TestSuite.runTest(TestSuite.java:232)at junit.framework.TestSuite.run(TestSuite.java:227)at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)试了各种方法都不行,除非注释掉aop。昨天搞了一晚上都没好,很是郁闷。
今天上午突然想起,前天替换了一些lib 包,于是找找被替换的包,在回收站里面,居然还在,还好我有不喜欢清理的坏习惯。把被替换的包重新导回来,发现可以用了。于是我把每一个被替换的都重新替换一次,最后发现是spring.jar出了问题,其实早就应该想到的。一直以为aspectJ出了问题。
用工具把两个包打开,发现可以用的是2.0版本,出问题的是2.0.8版本。
根据堆栈信息定位到,org.springframework.aop.aspectj.AbstractAspectJAdvice类的invokeAdviceMethodWithGivenArgs()方法。两个版本的方法大致是相同的,
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable { Object[] actualArgs = args; if (this.aspectJAdviceMethod.getParameterTypes().length == 0) actualArgs = null; try { if ((!Modifier.isPublic(this.aspectJAdviceMethod.getModifiers())) || (!Modifier.isPublic(this.aspectJAdviceMethod.getDeclaringClass().getModifiers()))) { this.aspectJAdviceMethod.setAccessible(true); } return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs); } catch (IllegalArgumentException ex) { throw new AopInvocationException("Mismatch on arguments to advice method [" + this.aspectJAdviceMethod + "]; pointcut expression [" + this.pointcut.getPointcutExpression() + "]", ex); //异常抛出处 } catch (InvocationTargetException ex) { } throw ex.getTargetException(); }可以很明显看到异常是因为return语句的invoke执行异常抛出的,这里的invoke()方法就是jdk中反射机制中的,也就是说问题出在参数actualArgs利用反射机制注入的过程中类型不匹配造成的。
利用debug看到两个版本的actualArgs参数对象,下面是2.0版本
下面是2.0.8版本
发现参数对象数组只有一个元素,就是MethodInvocationProceedingJoinPoint的对象,2.0版本的属性arguments有两个参数,当然了,这是aop代理的pointcut中方法的参数。但是在2.0.8版本中参数却为空。我想导致发生错误的原因就是这个MethodInvocationProceedingJoinPoint对象的问题。
在看一下这个对象是怎么产生的,定位到同类下的方法currentJoinPoint()
2.0版本
public static JoinPoint currentJoinPoint() { ReflectiveMethodInvocation rmi = (ReflectiveMethodInvocation)ExposeInvocationInterceptor.currentInvocation(); JoinPoint jp = (JoinPoint)rmi.getUserAttribute(JOIN_POINT_KEY); if (jp == null) { jp = new MethodInvocationProceedingJoinPoint(rmi); rmi.setUserAttribute(JOIN_POINT_KEY, jp); } return jp; }
2.0.8版本
public static JoinPoint currentJoinPoint() { MethodInvocation mi = ExposeInvocationInterceptor.currentInvocation(); if (!(mi instanceof ProxyMethodInvocation)) { throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi); } ProxyMethodInvocation pmi = (ProxyMethodInvocation)mi; JoinPoint jp = (JoinPoint)pmi.getUserAttribute(JOIN_POINT_KEY); if (jp == null) { jp = new MethodInvocationProceedingJoinPoint(pmi); pmi.setUserAttribute(JOIN_POINT_KEY, jp); } return jp; }
发现两个版本的实现机制不同,第一个事采用反射机制,第二个采用的是代理机制。由于本人水平有限,源代码就没有继续向下解析,我想造成错误的原因应该就是两种机制不同而引起的jp对象不同,至于根本原因,等有时间继续向下解析吧。如果有高手和前辈知道具体原因的,请留言告知,万分感谢。
- spring aop报Mismatch on arguments to advice method错误问题
- Spring AOP tx:advice
- Spring AOP之Advice
- Spring AOP Example – Advice
- Spring AOP Example – Advice
- Spring AOP Example – Advice
- spring aop 细说advice,advisor
- Spring AOP Schema aop:config、tx:advice
- Spring AOP Schema aop:config、tx:advice
- Spring AOP环绕型Advice简单例子
- Spring AOP 基本方式(Advice方式)
- spring tx:advice ...aop:config配置事物
- Spring AOP Advice接口-MethodBeforeAdvice+AfterReturningAdvice
- Spring3- Spring AOP——Advice
- Spring3系列:Spring AOP——Advice
- 16、spring AOP通知——Advice
- Spring AOP通知实例 – Advice
- Spring Aop中的advisor、advice、pointcut
- 4大 Java OSGi 框架比较 (Knopflerfish, Apache Felix, Equinox, Spring DM)
- Gluster分布式文件系统 使用(初阶篇)
- subscription open fllow
- Conversion to Dalvik format failed with error 1错误的解决
- SMART原则
- spring aop报Mismatch on arguments to advice method错误问题
- C++/CLI的泛型
- 结对编程
- ASP三层架构中可能出现的问题总结
- 仿Lightinthebox模版快速修改教程
- Maven基本知识点总结
- Leetcode: Binary Tree Inorder Traversal
- pci 总结
- Scrapy爬虫教程之URL解析与递归爬取