如何在Java中更改CLASSPATH? [英] How do you change the CLASSPATH within Java?

查看:165
本文介绍了如何在Java中更改CLASSPATH?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How do you change the CLASSPATH of a Java process from within the Java process?

你为什么要这样做?我会很快解释。

Before you ask me "Why would you want to do that?" I'll explain it shortly.


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

When you have a Clojure REPL running it is common to need more jars in your CLASSPATH to load a Clojure source file, and I'd like to do it without having to restart Clojure itself (which is not really an option when using it on Slime on Emacs).

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

That's the reason but I don't want this question tagged as some-weird-language some-weird-editor and be disregarded by the majority of Java developers that may have the answer.

推荐答案

一些一般意见:

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

you cannot (in a portable way that's guaranteed to work, see below) change the system classpath. Instead, you need to define a new ClassLoader.

ClassLoaders以分层方式工作,所以任何对X类的静态引用的类都需要加载与X相同的ClassLoader,或者在一个子ClassLoader中。你不能使用任何自定义ClassLoader来使代码由系统ClassLoader链接加载链接正确,如果以前不会这样做。因此,您需要安排您的主要应用程序代码在定制的ClassLoader中运行,除了您定位的额外代码外。

(说的是,破解所有在此示例扩展 URLClassLoader

ClassLoaders work in a hierarchical manner... so any class that makes a static reference to class X needs to be loaded in the same ClassLoader as X, or in a child ClassLoader. You can NOT use any custom ClassLoader to make code loaded by the system ClassLoader link properly, if it wouldn't have done so before. So you need to arrange for your main application code to be run in the custom ClassLoader in addition to the extra code that you locate.
(That being said, cracked-all mentions in the comments this example of extending the URLClassLoader)

您可能会考虑不要编写自己的ClassLoader,只是使用URLClassLoader。在父类classloaders网址中创建一个网址不是 的URLClassLoader。

And you might consider not writing your own ClassLoader, but just use URLClassLoader instead. Create a URLClassLoader with a url that are not in the parent classloaders url's.

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

A 更完整的解决方案将是:

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

If you assume the JVMs system classloader is a URLClassLoader (which may not be true for all JVMs), you can use reflection as well to actually modify the system classpath... (but that's a 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");

这篇关于如何在Java中更改CLASSPATH?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆