我想在我的應用程序啓動過程中增加一些代碼和附加功能。整個設置本身工作正常,但有一點我認爲javassist可能會生成錯誤的代碼。Javassist似乎生成無效的字段訪問代碼
我正在做一個特定類的具體方法,我之前檢查,返回值實際上是類型StringBuilder
或StringBuffer
。
ctMethod.insertAfter("$_.SOME_METHOD(); $_.SOME_FIELD = <...>;");
SOME_METHOD()和SOME_FIELD在AbstractStringBuilder
都聲明,的StringBuilder
和StringBuffer
超類。兩者都被定義爲公共的,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沒有正確地解決這個問題嗎? 我希望,我的解釋是可以理解的 - 否則讓我知道,我會盡力加強它。
好的,謝謝你的回答,我會在javassist項目中提出一個問題 - 或者你知道這個bug是否有一個? –
不知道一個。 –