我想找到或创建一个 Java 类加载器,它只加载系统类,不包括应用程序定义的类路径上的任何类。我的目标是使用该类加载器构建一个从特定 JAR 文件加载的类加载器,使用仅限系统的类加载器解析系统类,但不会用我的应用程序定义的任何类污染 JAR 文件中的类。
到目前为止,我还没有找到任何方法来创建既不使用私有(private) API 也不对 Java 实现做出假设的仅限系统的类加载器。请参阅下面的代码,该代码适用于我当前的环境,但做出了不受欢迎的假设。
如果没有办法创建一个实现独立的系统专用类加载器,有没有理由不这样做?我想做的事是个坏主意吗?
private ClassLoader createJarClassLoader(File f)
{
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
if (systemClassLoader instanceof URLClassLoader) {
URLClassLoader cl = (URLClassLoader) systemClassLoader;
URL[] urls = cl.getURLs();
List<URL> wantedURLs = new ArrayList<>();
for (URL u : urls) {
if (isSystemURL(u)) {
wantedURLs.add(u);
}
}
try {
wantedURLs.add(f.toURI().toURL());
} catch (MalformedURLException ex) {
return null;
}
return new URLClassLoader(wantedURLs.toArray(new URL[0]), null);
}
return null;
}
private boolean isSystemURL(URL u)
{
return u.getPath().contains("/jre/");
}
最佳答案
您需要将父类加载器设置为引导类加载器。在 java.lang.String 对象上调用 getClassLoader()
以获取引导类加载器并在您的类加载器构造函数中使用它。
public class MyClassLoader extends URLClassLoader {
protected MyClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent);
}
static MyClassLoader getInstance(URL[] urls) {
ClassLoader parent = "".getClass().getClassLoader();
return (new MyClassLoader(urls, parent));
}
}
引导类加载器的表示被记录为依赖于实现
Some implementations may use null to represent the bootstrap class loader. This method [getClassLoader] will return null in such implementations if this class was loaded by the bootstrap class loader.
但相同的措辞适用于 ClassLoader 构造函数中的父 ClassLoader,这意味着该解决方案是可移植的。
关于java - 需要一个 Java 系统专用的类加载器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34101259/