Ошибка при использовании лямбда в аспекте Java - PullRequest
0 голосов
/ 27 апреля 2018

У нас есть пользовательская аннотация:

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

И пользовательский @aspect, который перехватывает методы, отмеченные @AsyncWithTimeout следующим образом: работает нормально (обратите внимание на определение задачи, без лямбды)

@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 ...
   }
}

Однако, если мы вместо этого используем лямбду для инициализации задачи, выдается Исключение :

@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

Файл aop.xml в моем META-INF:

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

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

Должен ли я использовать лямбды в аспектах, или есть какое-то ограничение / ошибка? Любая помощь будет признательна.

Заранее спасибо.

1 Ответ

0 голосов
/ 27 апреля 2018

Что ж, я допустил ошибку в своем вопросе, и использовалась версия aspectjweaver на самом деле 1.8.0 вместо 1.9.1 .

РЕДАКТИРОВАТЬ : поскольку @kriegaex указывает в комментарии, ошибка уже устранена в версия 1.8.13 aspectjweaver (необязательно обновление до 1.9.1) Спасибо за указание.

Я только что проверил, что ошибка устранена в версии 1.8.13 и более поздних, поэтому лямбды можно использовать в аспектах без проблем.

...