首页 > 解决方案 > 使用 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()方法(即,如果我删除defineMethodand withoutCode),它会很好地工作。但是,一旦我向注释添加属性/方法,我就会得到这个异常:

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.access$300(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,这正是您对接口方法的期望。

关于我在这里缺少什么的任何想法?

标签: javajvmbyte-buddy

解决方案


当然,就在我即将完成我的问题时,我记得接口方法不仅需要是抽象的,它们还需要是公共的。修饰符值 0x400 表示该方法只是抽象的,而不是公共的。

因此,简单的解决方法是为方法属性添加公共可见性:

.defineMethod("value", TypeDescription.STRING, Visibility.PUBLIC)

推荐阅读