如何在运行时从java设置类路径

时间:2012-10-18 20:40:59

标签: java

  

可能重复:
  Setting CLASSPATH during runtime

可能的重复:Setting CLASSPATH during runtime

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

 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);

这种情况似乎有效。

2 个答案:

答案 0 :(得分:1)

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

  1. 类加载器表示命名空间(的一部分),不同类加载器加载的另外两个相同的类不是“相等”。这意味着在课堂加载中潜伏着一些危险,特别是单身人士突然不再如此单身,以及演员意外失败。
  2. 类加载器(应该)在尝试任何事情之前处理委托给“父”加载器的模式(见上文)。
  3. 类加载和链接是两个不同的步骤(尽管类加载器的示例实现,例如可以在博客文章/在线Java文章中找到,为了简单起见,将两者合并为一个)因此你不应该假设如果父类loader已经加载了一个类,它还加载了所有依赖项......
  4. 所有这一切都意味着如果加载器A加载的类A引用了既没有加载器A也没有加载任何父类的类B,则存在问题:类A可能在加载器A中加载很好但在使用时它失败了因为加载器A无法完全解析(链接)它。
  5. 你应该确保你的类加载器以同步方式加载类,否则步骤#1中暗示的问题可以从重复项中跳过,因为类加载器也可以从使用相同类加载器的多个线程重复...
  6. 注意:在您的程序的某个包装器脚本/批处理文件中使用-cp开关更容易

答案 1 :(得分:0)

来自ClassLoader#getSystemClassLoader() doc:

  

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

当您执行Thread.currentThread().setContextClassLoader(urlClassLoader)时,您正在更改当前线程中的引用,而不是ClassLoader中的引用(并且您无法更改此引用),因此从那时起您应该依赖在当前线程的新类加载器上加载类,如:

Thread.currentThread().getContextClassLoader().loadClass(...)