当前位置:  开发笔记 > 编程语言 > 正文

你如何在Java中更改CLASSPATH?

如何解决《你如何在Java中更改CLASSPATH?》经验,为你挑选了1个好方法。

如何从Java进程中更改Java进程的CLASSPATH?


在你问我之前"你为什么要那样做?" 我马上解释一下.

当你运行Clojure REPL时,通常需要在你的CLASSPATH中加入更多的jar来加载Clojure源文件,我想这样做而不必重新启动Clojure本身(在Slime上使用它时这不是一个真正的选择)在Emacs上).

这就是原因,但我不希望这个问题被标记为奇怪的语言奇怪的编辑器,并被大多数可能有答案的Java开发人员所忽视.



1> VonC..:

2017年第四季度更新:如下面由vda8888 评论,在Java 9中,系统不再是一个.java.lang.ClassLoaderjava.net.URLClassLoader

请参阅" Java 9迁移指南:七个最常见的挑战 "

我刚刚描述的类加载策略是以新类型实现的,而在Java 9中,应用程序类加载器属于该类型.
这意味着它URLClassLoader不再是,所以偶尔(URLClassLoader) getClass().getClassLoader()(URLClassLoader) ClassLoader.getSystemClassLoader()序列将不再执行.

java.lang.ModuleLayer将是一种替代方法,用于影响模块路径(而不是类路径).请参阅" Java 9模块 - JPMS基础知识 ".


对于Java 8或更低版本:

一些一般性意见:

你不能(以可移植的方式保证工作,见下文)改变系统类路径.相反,您需要定义一个新的ClassLoader.

ClassLoaders以分层方式工作...因此,任何对类X进行静态引用的类都需要在与X相同的ClassLoader中加载,或者在子类ClassLoader中加载.您不能使用任何自定义ClassLoader来正确地使系统ClassLoader链接加载代码,如果它之前没有这样做的话.因此,除了您找到的额外代码之外,您还需要安排主应用程序代码在自定义ClassLoader中运行.
(话虽如此,破解 - 所有人都在评论中提到这个扩展的 URLClassLoader例子)

你可能会考虑不编写自己的ClassLoader,而只是使用URLClassLoader.使用不在父类加载器URL中的URL创建URLClassLoader .

URL[] url={new URL("file://foo")};
URLClassLoader loader = new URLClassLoader(url);

一个更完整的解决方案将是:

ClassLoader currentThreadClassLoader
 = Thread.currentThread().getContextClassLoader();

// Add the conf dir to the classpath
// Chain the current thread classloader
URLClassLoader urlClassLoader
 = new URLClassLoader(new URL[]{new File("mtFile").toURL()},
                      currentThreadClassLoader);

// Replace the thread classloader - assumes
// you have permissions to do so
Thread.currentThread().setContextClassLoader(urlClassLoader);

如果您假设JVMs系统类加载器是URLClassLoader(对于所有JVM可能都不是这样),您也可以使用反射来实际修改系统类路径...(但这是一个hack;)):

public void addURL(URL url) throws Exception {
  URLClassLoader classLoader
         = (URLClassLoader) ClassLoader.getSystemClassLoader();
  Class clazz= URLClassLoader.class;

  // Use reflection
  Method method= clazz.getDeclaredMethod("addURL", new Class[] { URL.class });
  method.setAccessible(true);
  method.invoke(classLoader, new Object[] { url });
}

addURL(new File("conf").toURL());

// This should work now!
Thread.currentThread().getContextClassLoader().getResourceAsStream("context.xml");


在Linux上使用Java 1.6.0_13(64位)时,"更完整"的解决方案对我不起作用.另一方面,addURL方法按预期工作.
推荐阅读
N个小灰流_701
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有