在运行时将文件添加到 java 类路径
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1010919/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Adding files to java classpath at runtime
提问by
Is it possible to add a file (not necessarily a jar file) to java classpath at runtime. Specifically, the file already is present in the classpath, what I want is whether I can add a modified copy of this file to the classpath.
是否可以在运行时将文件(不一定是 jar 文件)添加到 java 类路径。具体来说,该文件已经存在于类路径中,我想要的是是否可以将此文件的修改副本添加到类路径中。
Thanks,
谢谢,
回答by akf
yes, you can. it will need to be in its package structure in a separate directory from the rest of your compiled code if you want to isolate it. you will then just put its base dir in the front of the classpath on the command line.
是的你可以。如果要隔离它,它需要位于与其余编译代码不同的目录中的包结构中。然后,您只需将其基本目录放在命令行上类路径的前面。
回答by ssteidl
Yes I believe it's possible but you might have to implement your own classloader. I have never done it but that is the path I would probably look at.
是的,我相信这是可能的,但您可能必须实现自己的类加载器。我从未这样做过,但这就是我可能会考虑的路径。
回答by Tobias Schulte
You coud try java.net.URLClassloader with the url of the folder/jar where your updated class resides and use it instead of the default classloader when creating a new thread.
您可以使用更新类所在的文件夹/jar 的 url 尝试 java.net.URLClassloader,并在创建新线程时使用它而不是默认类加载器。
回答by Thilo
You can only add folders or jar files to a class loader. So if you have a single class file, you need to put it into the appropriate folder structure first.
您只能将文件夹或 jar 文件添加到类加载器。因此,如果您只有一个类文件,则需要先将其放入适当的文件夹结构中。
Hereis a rather ugly hack that adds to the SystemClassLoader at runtime:
这是在运行时添加到 SystemClassLoader 的一个相当丑陋的 hack:
import java.io.IOException;
import java.io.File;
import java.net.URLClassLoader;
import java.net.URL;
import java.lang.reflect.Method;
public class ClassPathHacker {
private static final Class[] parameters = new Class[]{URL.class};
public static void addFile(String s) throws IOException {
File f = new File(s);
addFile(f);
}//end method
public static void addFile(File f) throws IOException {
addURL(f.toURL());
}//end method
public static void addURL(URL u) throws IOException {
URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class sysclass = URLClassLoader.class;
try {
Method method = sysclass.getDeclaredMethod("addURL", parameters);
method.setAccessible(true);
method.invoke(sysloader, new Object[]{u});
} catch (Throwable t) {
t.printStackTrace();
throw new IOException("Error, could not add URL to system classloader");
}//end try catch
}//end method
}//end class
The reflection is necessary to access the protected method addURL
. This could fail if there is a SecurityManager.
反射是访问受保护方法所必需的addURL
。如果有 SecurityManager,这可能会失败。
回答by Chase
Try this one on for size.
试试这个尺寸。
private static void addSoftwareLibrary(File file) throws Exception {
Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
method.setAccessible(true);
method.invoke(ClassLoader.getSystemClassLoader(), new Object[]{file.toURI().toURL()});
}
This edits the system class loader to include the given library jar. It is pretty ugly, but it works.
这将编辑系统类加载器以包含给定的库 jar。这很丑陋,但它有效。
回答by Ranjit Aneesh
The way I have done this is by using my own class loader
我这样做的方法是使用我自己的类加载器
URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
DynamicURLClassLoader dynalLoader = new DynamicURLClassLoader(urlClassLoader);
And create the following class:
并创建以下类:
public class DynamicURLClassLoader extends URLClassLoader {
public DynamicURLClassLoader(URLClassLoader classLoader) {
super(classLoader.getURLs());
}
@Override
public void addURL(URL url) {
super.addURL(url);
}
}
Works without any reflection
工作没有任何反射
回答by Guillermo Theler
My solution:
我的解决方案:
File jarToAdd = new File("/path/to/file");
new URLClassLoader(((URLClassLoader) ClassLoader.getSystemClassLoader()).getURLs()) {
@Override
public void addURL(URL url) {
super.addURL(url);
}
}.addURL(jarToAdd.toURI().toURL());