Я пытаюсь разработать совет, который оборачивает фактический вызов метода. Вот как я объявил мой перехватчик:
public class SecurityInterceptor() {
@RuntimeType
public Object intercept(
@SuperCall Callable<Object> supercall,
@This Object target,
@Origin Method method,
@AllArguments Object[] args) {
// Check args and annotations ...
Object obj = supercall.call();
// use Spring SPEL to post-process obj content ...
}
}
Перехватчик регистрируется следующим образом:
byte[] woven = new ByteBuddy().subclass(type)
.method(ElementMatchers.isAnnotatedWith(Secured.class))
.intercept(MethodDelegation.to(new SecurityInterceptor()))
.make().getBytes();
, где переплетенный байтовый массив управляется через механизм WeavingHook / WovenClass OSGi.
Как только загруженный класс загружается, я получаю следующее исключение:
java.lang.NoClassDefFoundError: com/contoso/users/service/provider/UsersServiceImpl (wrong name: com/contoso/users/service/provider/UsersServiceImpl$ByteBuddy$q3pXZ5KY)
at java.lang.ClassLoader.defineClass1(Native Method) ~[?:?]
at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[?:?]
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.defineClass(BundleWiringImpl.java:2410) ~[?:?]
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.findClass(BundleWiringImpl.java:2194) ~[?:?]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1607) ~[?:?]
at org.apache.felix.framework.BundleWiringImpl.access$200(BundleWiringImpl.java:80) ~[?:?]
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2053) ~[?:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:?]
at org.apache.felix.framework.Felix.loadBundleClass(Felix.java:1927) ~[?:?]
at org.apache.felix.framework.BundleImpl.loadClass(BundleImpl.java:978) ~[?:?]
Если я использую метод rebase
вместо subclass
и удаляю @SuperCall Callable<Object> supercall
аргумент, вызывается перехватчик.
Эта ошибка появляется только тогда, когда я применяю перехватчик в OSGi: та же процедура отлично работает в тестах vanilla java junit, где я изменяю классы следующим образом:
<T> T loadTestClass(Class<T> clazz) throws Exception {
return new ByteBuddy()
.subclass(clazz)
.method(ElementMatchers.isAnnotatedWith(Secured.class))
.intercept(MethodDelegation.to(securityInterceptor))
.make()
.load(getClass().getClassLoader())
.getLoaded()
.newInstance();
}
Есть идеи, как бороться с этой NoClassDefFoundError
/ неправильным именем ошибка?