我想找到或创建一个只加载系统类的Java类加载器,不包括应用程序定义的类路径上的任何类。我的目标是使用该类加载器构建一个类加载器,该加载器从特定的JAR文件加载,使用仅系统类加载器解析系统类,但不会使用我的应用程序定义的任何类来污染JAR文件中的类。 / p>
到目前为止,我还没有找到任何方法来创建一个只使用系统的类加载器,它不使用私有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/");
}
答案 0 :(得分:1)
您需要将父ClassLoader设置为bootstrap ClassLoader。在java.lang.String对象上调用getClassLoader()
以获取引导程序ClassLoader并在ClassLoader构造函数中使用它。
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));
}
}
bootstrap类加载器的表示形式记录为依赖于实现的
某些实现可能使用null来表示引导类加载器。如果此类由引导类加载器加载,则此方法[getClassLoader]将在此类实现中返回null。
但是相同的措辞适用于ClassLoader构造函数中的父ClassLoader,这意味着此解决方案是可移植的。