如果从中导入任何内容,为什么库需要成为构建路径的一部分?

时间:2012-11-05 05:10:00

标签: java reflection buildpath

考虑这个(半伪)代码:

private static final File file = new File("./archive.jar");
private static URLClassLoader classLoader;

public static void main(final String[] args) {
    try {
        classLoader = new URLClassLoader(new URL[] { file.toURI().toURL() });
        Method mainMethod = classLoader.loadClass("main class").getDeclaredMethod("main", String[].class);
        mainMethod.setAccessible(true);
        mainMethod.invoke(null, (Object) new String[] { "-arguments" });
    } catch(Exception e) {
        e.printStackTrace();
    }
}

...以及Eclipse IDE中的这两个项目设置:

First project setup. Second project setup.

提供的代码不会从JAR文件导入任何内容,但行为却不同。它有什么不同?好吧,在使用第一个项目设置时,在本网站的主题中会出现错误:

java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
Caused by: java.lang.StackOverflowError
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)

该行发生错误:

mainMethod.invoke(null, (Object) new String[] { "-arguments" });

但是,使用第二个项目设置(JAR是构建路径的一部分)时,不会发生错误。除此之外,使用第一个项目设置时代码根本不起作用。我知道当它正常工作时会发生什么,并且第一个项目设置不会发生,但它与第二个项目设置不同。值得一提的另一件事是代码只有在JAR文件位于Eclipse中Order和Exports列表的顶部时才有效:

Order and Export list.

为什么会这样?如果没有从JAR导入任何内容,为什么它需要成为构建路径的一部分才能工作?类加载器根据实际文件使用它,因此它与项目的构建路径相关联无关紧要。

1 个答案:

答案 0 :(得分:3)

StackOverflowError通常表示调用循环。在这种情况下,我认为JVM可能正在寻找它需要的东西,例如检查它试图链接的类是否有效。

需要链接才能运行方法,并涉及验证和符号引用的解析。

为了进一步了解没有库的问题,有必要查看主类的代码以了解它所引用的内容。

不要在Java中导入过多的意义。它只允许你使用类名而不完全限定它们:ArrayList,而不是java.util.ArrayList。