2017-08-24 180 views
0

我想在我的应用程序启动过程中增加一些代码和附加功能。整个设置本身工作正常,但有一点我认为javassist可能会生成错误的代码。Javassist似乎生成无效的字段访问代码

我正在做一个特定类的具体方法,我之前检查,返回值实际上是类型StringBuilderStringBuffer

ctMethod.insertAfter("$_.SOME_METHOD(); $_.SOME_FIELD = <...>;"); 

SOME_METHOD()和SOME_FIELD在AbstractStringBuilder都声明,的StringBuilderStringBuffer超类。两者都被定义为公共的,java.lang.AbstractStringBuilder本身只是包私有的。

操作本身是成功的,但执行此代码会导致错误“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参考。

所以我的问题是:我监督了一些关于JVMs可见性和继承的概念,或者javassist没有正确地解决这个问题吗? 我希望,我的解释是可以理解的 - 否则让我知道,我会尽力加强它。

回答

1

这是Javassist中的错误。

字段不是虚拟的,通过命名另一个类,您确实可以访问需要由相关类访问的不同(阴影)字段。

+0

好的,谢谢你的回答,我会在javassist项目中提出一个问题 - 或者你知道这个bug是否有一个? –

+1

不知道一个。 –