私は、クラスを動的にロードし、オブジェクトを作成し、そのメソッドの1つを呼び出さなければならない非常に複雑なJavaソフトウェアを持っています。いくつかの状況では、ロードされたクラスが別のクラスを参照している場合、NoClassDefFoundError
(ClassNotFoundException
によって引き起こされる)が発生することがあります。この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.Foo
とbaz.Baz
の両方がurl
で示されるパスにあります。私が見ることができる唯一の違いは、go()
メソッドが呼び出された瞬間です。
ここで何が間違っていますか?
いくつかの情報が欠落しています:どのパッケージが入りますか? URLClassloaderに渡されるURLは何ですか?コンパイラはFooのロードをサブクラスGoとして受け入れ、それを '' 'に代入しますか? Foo'''を拡張? –