У нас есть пользовательская аннотация:
@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>
Должен ли я использовать лямбды в аспектах, или есть какое-то ограничение / ошибка?
Любая помощь будет признательна.
Заранее спасибо.