2016-06-24 12 views
0

私は、クラスを動的にロードし、オブジェクトを作成し、そのメソッドの1つを呼び出さなければならない非常に複雑なJavaソフトウェアを持っています。いくつかの状況では、ロードされたクラスが別のクラスを参照している場合、NoClassDefFoundErrorClassNotFoundExceptionによって引き起こされる)が発生することがあります。このURLClassLoaderが動作することがあり、時には動作しないことがあるのはなぜですか?

は、我々が持っていると言う:

package baz; 
public class Baz { 
    public static final int BAZ = 111; 
    ... 
} 

は、クラスがこのようにロードされていると言う

package foo; 
import static baz.Baz.BAZ; 
public class Foo implements Go { 
    @Override 
    void go() { 
     ... 
     something = BAZ; 
     ... 
    } 
} 

public interface Go { 
    void go(); 
} 

をロードするクラスであることを言います

try (final URLClassLoader loader = new URLClassLoader(new URL[] { url })) { 
    final Class<? extends Foo> clazz = 
     loader.loadClass("foo.Foo").asSubclass(Go.class); 
    this.obj = clazz.newInstance(); 
    this.obj.go(); 
} catch ... 

すべてが機能します。代わりに、あなたは物事にこの他の方法で行うことを言う:

try (final URLClassLoader loader = new URLClassLoader(new URL[] { url })) { 
    final Class<? extends Foo> clazz = 
     loader.loadClass("foo.Foo").asSubclass(Go.class); 
    this.obj = clazz.newInstance(); 
    //we do not invoke go() now... 
} catch ... 

//later, in another method... 
this.obj.go(); 

を今すぐgo()の呼び出しは、それがbaz.Bazをロードすることはできません文句、NoClassDefFoundErrorを発生させます。もちろん、URLは同じです。もちろんfoo.Foobaz.Bazの両方がurlで示されるパスにあります。私が見ることができる唯一の違いは、go()メソッドが呼び出された瞬間です。

ここで何が間違っていますか?

+0

いくつかの情報が欠落しています:どのパッケージが入りますか? URLClassloaderに渡されるURLは何ですか?コンパイラはFooのロードをサブクラスGoとして受け入れ、それを '' 'に代入しますか? Foo'''を拡張? –

答えて

2

ここで何が間違っていますか?

は、私はこの問題は、このあると思う:あなたはtryブロックを終了するときにクラスローダがクローズされることになります

try (final URLClassLoader loader = new URLClassLoader(new URL[] { url })) { 

close()方法のjavadocは言う:もはや、このローダによって定義され、新しいクラスやリソースをロードするために使用することができないように

は、このURLClassLoaderのを閉じます。 go()メソッドを呼び出す

Goクラスのクラス初期化をトリガされ、それはBazクラスがロードおよび初期化する原因となっているものです。後者のクラスローディングが、クラスローダが閉じられた後に発生すると、失敗することになります。

+0

おっと。あなたが正しい。 –

1

クラスが他のクラスに依存する場合、これらは遅延ロードです。

つまり、ローディングfoo.FOOは、同時にロードされません。baz.BAZ後者は、最初にアクセスされるときに読み込まれます。あなたのケースでは、go()へのメソッド呼び出しもそれをロードします。 2番目の例では

は、メソッドgo()が呼び出された時点で、URLClassLoaderはすでにあるを閉じた - のtry-と資源文で。したがって、クラスをもう読み込むことはできません。

関連する問題