2017-08-24 8 views
0

私のアプリケーションの起動時に追加の機能を持つコードを追加しようとしています。全体のセットアップ自体はうまくいきますが、javassistが悪いコードを生成するかもしれないと思うところが1つあります。Javassistが無効なフィールドアクセスコードを生成しているようです

特定のクラスの特定のメソッドでこれを実行していますが、戻り値が実際にはStringBuilderまたはStringBufferの型であることを前に確認しました。

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

SOME_METHOD()とSOME_FIELDはAbstractStringBuilderで宣言された両方、StringBuilderStringBufferのスーパークラスです。両方とも公開として定義されており、java.lang.AbstractStringBuilder自体はpackage-privateのみです。

操作自体は成功しましたが、このコードを実行するとエラー "java.lang.IllegalAccessError: tried to access class java.lang.AbstractStringBuilder from class <...>"が発生します。私が知っている印刷デバッグでは、メソッドへのアクセスはうまくいくが、フィールドへのアクセスはクラッシュする。 StringBuilderに自分自身をそれの解決方法にアクセスするためにそう

... 
invokevirtual #41 <java/lang/StringBuilder.SOME_METHOD> 
... 
getfield #72 <java/lang/AbstractStringBuilder.SOME_FIELD> 
... 

が、フィールドのために、それは明らかに変更されたコードの場所からアクセスすることはできませんされていないAbstractStringBuilderに解決:

は、だから私は、生成されたバイトコードをチェックします。 Btw、逆コンパイルされたバイトコードはうまく見えます。

私も自分の静的コードでは、このフィールドにアクセスしていますが、私はこの1のバイトコードを確認:

... 
getfield #37 <java/lang/StringBuilder.SOME_FIELD> 
... 

これはデフォルトのコンパイラによってコンパイルされたコードであり、それは参考のためにAbstractStringBuilder使用していません。

私の質問は、私は可視性と継承に関するJVMの概念に関することを監督しましたか、javassistはこれを正しく解決していませんか? 私の説明は理解できると思います。そうでなければ私に知らせてください。私はそれを強化しようとします。

答えて

1

これはJavassistのエラーです。

フィールドは仮想ではありません。別のクラスの名前を付けると、問題のクラスからアクセス可能な別の(影付きの)フィールドに実際にアクセスします。

+0

あなたの答えをありがとう、私はjavassistプロジェクトで問題を提起する - またはすでにこのバグのものがあるかどうか知っていますか? –

+1

分かりません。 –

関連する問題