osgi - OSGi 中的 bytebuddy rebase 与子类和错误名称/NoClassDefFoundError
问题描述
我正在尝试开发一个包含方法实际调用的建议。这就是我声明我的拦截器的方式:
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
/错误名称错误的任何想法?
解决方案
OSGi 类加载器实现通常使用ClassLoader.defineClass
将预期类名作为参数的方法:例如https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/lang/ClassLoader .html#defineClass(java.lang.String,byte%5B%5D,int,int)。当提供预期的类名时,类加载器要求被定义的类的名称与预期的类名匹配。这是一个很好的健全性检查。
因此,如果类加载器正在定义类 Foo,则不能为具有不同名称的类(例如子类)提供字节数组。
推荐阅读
- flutter - Flutter Left-aligned Column with image & label,在ListTile中不会垂直扩展和裁剪图像
- html - 滚动条为被部分阻碍
我在一组滚动图片()下方放置了一个深灰色三角形()。#scrollbox 的滚动条被三角形部分遮挡。我试过设置一个 z-index ,但没有解决这个问题。我重新安排了我的 div 结构,以防我搞砸了,但我很确定这一切都是正确的。这是直接 html/css。
如果stackoverflow的任何明智的居民可以提供帮助,我们将不胜感激。
- sql - 在 Postgres 中设置事务回滚的默认值
- oracle - 建立主从关系时的问题
- c# - 由于某种原因,使用带有 2 个 Where 子句的 LINQ 方法将不起作用
- sql - SESSION_CONTEXT 返回 NULL
- python-3.x - 从命令提示符执行我的脚本时无法导入 opencv
- powershell - 如果脚本文件位于包含空格的位置,则从 CMD 调用 powershell 脚本会出错
- clickhouse - Clickhouse - 如何按日期在数组中聚合超出此日期的数据?
- git - 如何使用 Android Studio 和 Typescript 制作 Android Chat-App?[可能与 WebRTC 和 Websocket 服务器一起使用]