【问题标题】:Creating an annotation interface with ByteBuddy使用 ByteBuddy 创建注释接口
【发布时间】:2020-02-28 07:26:01
【问题描述】:

我正在尝试使用 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),它的效果很好。但是,一旦我向注释添加属性/方法,我就会得到这个异常:

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

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

【问题讨论】:

  • 似乎只是创建注释的复杂方法

标签: java jvm byte-buddy


【解决方案1】:

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

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

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

【讨论】:

  • 接口方法也可以是private。但是,publicprivate 中的任何一个都没有,这意味着 package-private 又名默认访问,这对于接口方法是不允许的。
  • 好点,@Holger,我忘了也有这种可能性。
  • 这是字节好友中缺少的验证。在未来的版本中,您会收到更好的错误消息。
  • 谢谢@RafaelWinterhalter,这将是一个不错的改进!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
  • 2018-05-18
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多