2012-12-28 3 views
9

java.lang.IllegalAccessError: tried to access field ConcreteEntity.instance from class Entityjava.lang.IllegalAccessError:クラスEntityからフィールドConcreteEntity.instanceにアクセスしようとしました

私は、デフォルトのClassLoaderの中に存在するアクセスタイプdefaultのフィールドであるConcreteEntity.instanceにアクセスしようとしています。Entity.getInstanceは、子にあるメソッドClassLoaderです。

ここで、それらは同じパッケージに入っていますが、IllegalAccessErrorがスローされていることに注意してください。この問題の解決策はありますか?ClassLoaderと同じエンティティクラスを実際にロードすることはありません。ConcreteEntity

0 new #14 <Entity> 
3 dup 
4 aload_0 
5 invokevirtual #18 <Adapter.getInstance> 
8 checkcast #20 <sl> 
11 getfield #24 <sl.d> 
14 invokespecial #25 <Entity.<init>> 
17 areturn 

jclasslibで取得されたバイトコードは、例外として「コンパイル後に」生成されました。

投稿を削除していただきありがとうございます。

+0

あなたはバイトコードコンパイラのいくつかの種類を使用して、実行時に、あなたのクラスを変更しているセクション5.3、the jvm spceificationからの引用? –

+0

はい私はそうです。しかし、操作されるバイトコードは完璧です。 – Justin

+0

スーパークラス内のサブクラスフィールドにアクセスしようとしていますか?それは許されないことだと思う。 –

答えて

27

あなたのケースで、あなたが複数のクラスローダを扱っていることは明らかである以外、a similar questionmy answerを参照してください:

JVMは異なるクラスローダからロードされたクラスは、彼らが持っている場合でも、異なる「実行時パッケージ」にあると考えて同じパッケージ名。

At run time, a class or interface is determined not by its name alone, but by a pair: its fully qualified name and its defining class loader. Each such class or interface belongs to a single runtime package. The runtime package of a class or interface is determined by the package name and defining class loader of the class or interface.

そして、セクション5.4.4で:

A field or method R is accessible to a class or interface D if and only if any of the following conditions is true:

...

R is either protected or package private (that is, neither public nor protected nor private), and is declared by a class in the same runtime package as D.

+0

本当に面白いです。だから、あなたの頭の上の何かの仕事を知っていますか? 私の実装を変更する必要がある "悲しいことに、それを単一のクラスローダーに持ち込む"か、B)JVMSpecのクラスローディングでさらに研究を行う – Justin

+0

'Entity'が' ConcreteEntity'が保護されている必要があります。ランタイムパッケージのコンセプトはセキュリティ上の理由から存在するため、回避策はないと思います。 –

+0

私はあなたの答えをありがとう。それは何が起こっているのかを明らかにした。それは受け入れられたとマークされています。 – Justin

1

Javadoc:通常、このエラーはコンパイラによって検出されます。このエラーは、クラスの定義が互換性なく変更された場合にのみ実行時に発生します。

難しいクラス操作が試されているかもしれませんが、おそらくクラスローディングで、両方のクラスがどのようにロードされるかに時間を費やしています。まれに、明示的なserialVersionIdが役立つ場合があります。

クラスが関連している場合(スーパー/サブクラス)、インターフェイスを使用してその関係を削除しようとします。おそらく注射を使用する。 これはクラスを2回参照/ロードしません。

申し訳ありませんが、私が与えることができない具体的な答えです。

+0

それは私が想定している低レベルのエンジニアリングの問題です。しかし、私が間違っていないなら、通常の状況下ではこのフィールドを参照するのに問題はありませんか? 悲しいことに、難読化ツールがテスト環境内でどのように動作するかによって、私は別のルートを見つけなければならないかもしれません。 – Justin

関連する問題