使用 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() 方法(即,如果我删除 defineMethodwithoutCode),这个效果很好。但是,一旦我在注释中添加 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)