【问题标题】:Error using lambda in java aspect在 java 方面使用 lambda 时出错
【发布时间】:2018-04-27 09:21:52
【问题描述】:

我们有一个自定义注解:

@Target(value = {ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface AsyncWithTimeout {
   long timeout();
}

还有一个自定义的@aspect,它拦截@AsyncWithTimeout注释的方法如下,工作正常(注意任务定义,没有lambda)

@Aspect
public class AsyncWithTimeoutInterceptor {

   @Around(value = "@within(com.foo.AsyncWithTimeout) || " + "@annotation(com.foo.AsyncWithTimeout)")
   public Object asyncWithTimeout(ProceedingJoinPoint point) {  
     long timeout = ((MethodSignature) point.getSignature()).getMethod().getAnnotation(AsyncWithTimeout.class).timeout()

     // Task without lambda -> OK
     Callable<Object> task = new Callable<Object>() {
        public Object call() {
           try {
              // Do some stuff with the timeout...
           } catch (Throwable throwable) {
              // Do some stuff...
           }
        }
     };

     // Do some stuff ...
   }
}

但是,如果我们使用 lambda 代替初始化任务,则会抛出 Exception

@Aspect
public class AsyncWithTimeoutInterceptor {

   @Around(value = "@within(com.foo.AsyncWithTimeout) || " + "@annotation(com.foo.AsyncWithTimeout)")
   public Object asyncWithTimeout(ProceedingJoinPoint point) {  
     long timeout = ((MethodSignature) point.getSignature()).getMethod().getAnnotation(AsyncWithTimeout.class).timeout()

     // Task with lambda -> Error
     Callable<Object> task = () -> {
        try {
           // Do some stuff with the timeout...
        } catch (Throwable throwable) {
           // Do some stuff...
        }
     };

     // Do some stuff ...
   }
}

异常详情:

java.lang.IllegalStateException: there is no classname for invokedynamic
        at org.aspectj.apache.bcel.generic.InvokeDynamic.getClassName(InvokeDynamic.java:126)
        at org.aspectj.weaver.bcel.BcelAccessForInlineMunger.openAroundAdvice(BcelAccessForInlineMunger.java:141)
        at org.aspectj.weaver.bcel.BcelAccessForInlineMunger.munge(BcelAccessForInlineMunger.java:80)
        at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:441)
        at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:101)
        at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1689)
        at org.aspectj.weaver.bcel.BcelWeaver.weaveWithoutDump(BcelWeaver.java:1633)
        at org.aspectj.weaver.bcel.BcelWeaver.weaveAndNotify(BcelWeaver.java:1398)
        at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1155)
        at org.aspectj.weaver.tools.WeavingAdaptor.getWovenBytes(WeavingAdaptor.java:527)
        at org.aspectj.weaver.tools.WeavingAdaptor.weaveClass(WeavingAdaptor.java:363)
        at org.aspectj.weaver.loadtime.Aj.preProcess(Aj.java:121)
        at org.aspectj.weaver.loadtime.ClassPreProcessorAgentAdapter.transform(ClassPreProcessorAgentAdapter.java:54)
        at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
        at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:763)

编辑:实际上 aspectjweaver 版本是 1.8.0

使用的版本:jdk 1.8.0_124、aspectjweaver 1̶.̶9̶.̶1̶1.8.0

我的 META-INF 中的文件 aop.xml

<aspectj>
   <aspects>
      <aspect name="com.foo.AsyncWithTimeoutInterceptor"/>
   </aspects>

   <weaver>
      <include within="com.foo.*"/>
   </weaver>
</aspectj>

我应该能够在方面使用 lambda,还是存在某种限制/错误? 任何帮助将不胜感激。

提前致谢。

【问题讨论】:

  • 听起来更像是某些 AspectJ 跟踪器上的错误条目,但仍然:有趣的观察!
  • 感谢@GhostCat 的评论!你完全正确。我在我的问题中犯了一个错误,使用的 aspecjweaver 版本实际上是 1.8.0,实际上是 1.8.0 而不是 1.9.1。我刚刚检查了该错误在 1.9.1 版本中已解决:/
  • @troig 在这种情况下,您可以简单地删除问题,或者自己回答
  • 完成@Eugene!我更喜欢保留这个问题,也许可以帮助其他人使用旧的 aspectjweaver 版本。谢谢你的建议:)

标签: java lambda annotations aop aspectj


【解决方案1】:

好吧,我的问题弄错了,使用的 aspectjweaver 版本实际上是 1.8.0 而不是 1.9.1

编辑:正如@kriegaex 在评论中指出的那样,该错误已在 1.8.13 aspectjweaver 版本(无需升级到 1.9.1) 感谢您指出。

我刚刚检查了错误在1.8.13及更高版本中得到解决,所以lambdas可以在没有问题的方面使用。

【讨论】:

  • 为什么你用的是1.8.0而不是最新的1.8版本1.8.13?在 1.8 系列发行版中有许多错误修正,也在 Eclipse 编译器的上游,这是(分叉但定期更新)AspectJ 编译器的基础。很有可能它会起作用,我认为没有必要使用主要支持 Java 9 和部分 Java 10 的全新 1.9.1 版本。
  • 嗨@kriegaex!感谢您的评论。老实说,我不确定我们为什么使用 1.8.0 版本。很久以前它就在我们的生产服务器中。当问题的错误出现时,我的第一个想法是尝试使用最新的 1.9.1。不管怎样,我会听从你的建议,我会尝试升级到 1.8.3。也许就足够了...再次感谢!
  • 注意,那是 1.8.13,不是 1.8.3。
  • @kriegaex 你是对的,该错误已在 1.8.13 中修复。我已经编辑了我的原始答案。谢谢
猜你喜欢
  • 2016-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多