Javassist 似乎生成了无效的字段访问代码
Javassist seems to generate invalid field access code
我正在尝试在我的应用程序启动期间使用附加功能来扩充一些代码。整个设置本身运行良好,但有一点我认为 javassist 可能会生成错误代码。
我在特定 class 的特定方法上执行此操作,我之前检查过 return 值实际上是 StringBuilder
或 StringBuffer
类型。
ctMethod.insertAfter("$_.SOME_METHOD(); $_.SOME_FIELD = <...>;");
SOME_METHOD() 和SOME_FIELD 都在AbstractStringBuilder
中声明,StringBuilder
和StringBuffer
的superclass。两者都定义为 public,java.lang.AbstractStringBuilder
本身只是 package-private.
操作本身是成功的,但执行此代码会导致错误“java.lang.IllegalAccessError: tried to access class java.lang.AbstractStringBuilder from class <...>
”。通过打印调试我发现,访问方法工作正常但访问字段崩溃。
所以我检查了生成的字节码:
...
invokevirtual #41 <java/lang/StringBuilder.SOME_METHOD>
...
getfield #72 <java/lang/AbstractStringBuilder.SOME_FIELD>
...
因此,为了访问方法,它解析为 StringBuilder
本身,但对于字段,它解析为 AbstractStringBuilder,这显然不能从修改代码的位置访问。顺便说一句,反编译后的字节码看起来还不错。
我也是在我的静态代码中访问这个字段,所以我查看了这个的字节码:
...
getfield #37 <java/lang/StringBuilder.SOME_FIELD>
...
这是编译器默认编译的代码,没有引用AbstractStringBuilder。
所以我的问题是:我是否监督了有关 JVM 可见性和继承概念的某些事情,或者 javassist 没有正确解决这个问题?
我希望,我的解释是可以理解的 - 否则请告诉我,我会尽力改进它。
这是 Javassist 中的一个错误。
字段不是虚拟的,通过命名另一个 class,您实际上访问了一个不同的(阴影)字段,需要由相关的 class 访问。
我正在尝试在我的应用程序启动期间使用附加功能来扩充一些代码。整个设置本身运行良好,但有一点我认为 javassist 可能会生成错误代码。
我在特定 class 的特定方法上执行此操作,我之前检查过 return 值实际上是 StringBuilder
或 StringBuffer
类型。
ctMethod.insertAfter("$_.SOME_METHOD(); $_.SOME_FIELD = <...>;");
SOME_METHOD() 和SOME_FIELD 都在AbstractStringBuilder
中声明,StringBuilder
和StringBuffer
的superclass。两者都定义为 public,java.lang.AbstractStringBuilder
本身只是 package-private.
操作本身是成功的,但执行此代码会导致错误“java.lang.IllegalAccessError: tried to access class java.lang.AbstractStringBuilder from class <...>
”。通过打印调试我发现,访问方法工作正常但访问字段崩溃。
所以我检查了生成的字节码:
...
invokevirtual #41 <java/lang/StringBuilder.SOME_METHOD>
...
getfield #72 <java/lang/AbstractStringBuilder.SOME_FIELD>
...
因此,为了访问方法,它解析为 StringBuilder
本身,但对于字段,它解析为 AbstractStringBuilder,这显然不能从修改代码的位置访问。顺便说一句,反编译后的字节码看起来还不错。
我也是在我的静态代码中访问这个字段,所以我查看了这个的字节码:
...
getfield #37 <java/lang/StringBuilder.SOME_FIELD>
...
这是编译器默认编译的代码,没有引用AbstractStringBuilder。
所以我的问题是:我是否监督了有关 JVM 可见性和继承概念的某些事情,或者 javassist 没有正确解决这个问题? 我希望,我的解释是可以理解的 - 否则请告诉我,我会尽力改进它。
这是 Javassist 中的一个错误。
字段不是虚拟的,通过命名另一个 class,您实际上访问了一个不同的(阴影)字段,需要由相关的 class 访问。