【发布时间】:2016-06-24 23:26:50
【问题描述】:
我有一个相当复杂的 Java 软件,它必须动态加载一个类、创建一个对象并调用其中一个方法。事实证明,在某些情况下,如果加载的类引用另一个类,则会引发 NoClassDefFoundError(由 ClassNotFoundException 引起)。
假设我们有:
public interface Go {
void go();
}
说要加载的类是:
package foo;
import static baz.Baz.BAZ;
public class Foo implements Go {
@Override
void go() {
...
something = BAZ;
...
}
}
在哪里
package baz;
public class Baz {
public static final int BAZ = 111;
...
}
说类是这样加载的:
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() 会引发NoClassDefFoundError,抱怨它无法加载baz.Baz。当然,网址是一样的。当然foo.Foo 和baz.Baz 都在url 指示的路径中。我能看到的唯一区别是调用go() 方法的那一刻。
这里有什么问题?
【问题讨论】:
-
缺少一些信息:Go 在哪个包中?传递给 URLClassloader 的 URL 是什么?编译器是否接受 Foo 作为子类 Go 的加载,然后将其分配给
? extends Foo?
标签: java classloader urlclassloader