2

可能重复:
在运行时设置 CLASSPATH

可能重复:在运行时设置 CLASSPATH

要获取我正在使用的类路径:

 ClassLoader cl = ClassLoader.getSystemClassLoader();
     URL[] urls = ((URLClassLoader)cl).getURLs();
     for(URL url: urls){
         System.out.println("classpath:"+url.getFile());
         }

有人可以帮助我编写代码以在运行时将 jar 加载到类路径中。

ClassLoader currentThreadClassLoader
     = Thread.currentThread().getContextClassLoader();
    URLClassLoader urlClassLoader
     = new URLClassLoader(new URL[]{new File("D:\\ms.jar").toURL()},
                          currentThreadClassLoader);
    Thread.currentThread().setContextClassLoader(urlClassLoader);

这似乎行不通。

4

2 回答 2

1

一个完整的(编码的)解决方案将有点超出单个 Stack Overflow 的答案,所以如果您决定编写自己的 ClassLoader,我将概述您需要注意的要点:

  1. 类加载器代表一个命名空间(部分),并且由不同类加载器加载的两个其他相同的类不是“相等的”。这意味着在类加载中潜伏着一些危险,特别是单例突然不再那么单一,以及演员阵容意外失败。
  2. 在尝试自己做任何事情之前,类加载器(应该)以委托给“父”加载器的模式工作(见上文)。
  3. 类加载和链接是两个不同的步骤(尽管可以在博客文章/在线 Java 文章中找到类加载器的示例实现,但为简单起见,将两者合二为一)因此,您不应假设如果父加载器已加载它还加载了所有依赖项的类...
  4. 这意味着如果加载器 A 加载的类 A 引用了加载器 A 或其任何父级都无法加载的类 B,则会出现问题:类 A 可能在加载器 A 中加载得很好,但在使用时它会失败,因为加载器 A无法完全解决(链接)它。
  5. 并且您应该确保您的类加载器以同步的方式加载类,否则在步骤#1 中提示的问题可能会从由于类加载器的重复到使用相同类加载器的多个线程的重复...

注意:在您的程序的一些包装脚本/批处理文件中使用该开关要容易得多。-cp

于 2012-10-18T21:11:18.390 回答
0

ClassLoader#getSystemClassLoader()文档:

此方法首先在运行时启动序列的早期调用,此时它创建系统类加载器并将其设置为调用线程的上下文类加载器。

当您这样做时Thread.currentThread().setContextClassLoader(urlClassLoader),您正在更改当前线程中的引用,而不是其中的引用ClassLoader (并且您无法更改此引用),因此从那时起您应该依靠当前线程的新类加载器来加载您的类有类似的东西:

Thread.currentThread().getContextClassLoader().loadClass(...) 
于 2012-10-18T21:12:10.247 回答