使用 ByteBuddy 创建注解界面
Creating an annotation interface with ByteBuddy
我正在尝试使用 ByteBuddy 生成一个带有 String value()
属性的简单注释界面。我正在使用以下代码(Xtend 语法,但你明白了):
new ByteBuddy()
.makeInterface(Annotation)
.merge(Visibility.PUBLIC)
.name("fxxx.lang.Annotation")
.defineMethod("value", TypeDescription.STRING)
.withoutCode
.make.load(class.classLoader).loaded
如果没有 value()
方法(即,如果我删除 defineMethod
和 withoutCode
),这个效果很好。但是,一旦我在注释中添加 attribute/method,我就会得到这个异常:
java.lang.ClassFormatError: Method value in class fxxx/lang/Annotation has illegal modifiers: 0x400
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader.access0(ByteArrayClassLoader.java:40)
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader$ClassDefinitionAction.run(ByteArrayClassLoader.java:614)
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader$ClassDefinitionAction.run(ByteArrayClassLoader.java:566)
at java.security.AccessController.doPrivileged(Native Method)
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader.findClass(ByteArrayClassLoader.java:339)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader.load(ByteArrayClassLoader.java:289)
at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default$WrappingDispatcher.load(ClassLoadingStrategy.java:342)
at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default.load(ClassLoadingStrategy.java:128)
at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:85)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:5468)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:5457)
我对这个异常感到非常困惑,因为 0x400 是 ACC_ABSTRACT
,这正是您对接口方法的期望。
关于我在这里遗漏了什么有什么想法吗?
当然,我的问题快写完了,我记得接口方法不仅要抽象,还要public。修饰符值 0x400 表示该方法只是 抽象,而不是 public.
因此,简单的解决方法是为方法属性添加 public 可见性:
.defineMethod("value", TypeDescription.STRING, Visibility.PUBLIC)
我正在尝试使用 ByteBuddy 生成一个带有 String value()
属性的简单注释界面。我正在使用以下代码(Xtend 语法,但你明白了):
new ByteBuddy()
.makeInterface(Annotation)
.merge(Visibility.PUBLIC)
.name("fxxx.lang.Annotation")
.defineMethod("value", TypeDescription.STRING)
.withoutCode
.make.load(class.classLoader).loaded
如果没有 value()
方法(即,如果我删除 defineMethod
和 withoutCode
),这个效果很好。但是,一旦我在注释中添加 attribute/method,我就会得到这个异常:
java.lang.ClassFormatError: Method value in class fxxx/lang/Annotation has illegal modifiers: 0x400
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader.access0(ByteArrayClassLoader.java:40)
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader$ClassDefinitionAction.run(ByteArrayClassLoader.java:614)
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader$ClassDefinitionAction.run(ByteArrayClassLoader.java:566)
at java.security.AccessController.doPrivileged(Native Method)
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader.findClass(ByteArrayClassLoader.java:339)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader.load(ByteArrayClassLoader.java:289)
at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default$WrappingDispatcher.load(ClassLoadingStrategy.java:342)
at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default.load(ClassLoadingStrategy.java:128)
at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:85)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:5468)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:5457)
我对这个异常感到非常困惑,因为 0x400 是 ACC_ABSTRACT
,这正是您对接口方法的期望。
关于我在这里遗漏了什么有什么想法吗?
当然,我的问题快写完了,我记得接口方法不仅要抽象,还要public。修饰符值 0x400 表示该方法只是 抽象,而不是 public.
因此,简单的解决方法是为方法属性添加 public 可见性:
.defineMethod("value", TypeDescription.STRING, Visibility.PUBLIC)