大家好,感谢您的关注!我有一个必须既简单又明显的问题,但我却陷入困境。
我想通过自定义类加载器提供动态创建的 Java 类,供第三方库使用。
现在我的问题是:当我自己不直接加载这些类时,如何设置自定义类加载器来加载这些类?
我想当我使用我的ClassLoader加载某个类时,它就成为了这个类的ClassLoader,并且从该类加载的所有类都将通过我的ClassLoader进行引导。
我按照官方教程创建了一个自定义类加载器:http://java.sun.com/developer/onlineTraining/Security/Fundamentals/magercises/ClassLoader/help.html http://java.sun.com/developer/onlineTraining/Security/Fundamentals/magercises/ClassLoader/help.html.
public class DynamicClassloader extends ClassLoader {
private Map<String, Class<?>> classesMap = new HashMap<String, Class<?>>();
public DynamicClassloader(ClassLoader parent) {
// Also tried super(parent);
super(sun.misc.Launcher.getLauncher().getClassLoader());
}
// Adding dynamically created classes
public void defineClass(String name, Class<?> clazz) {
classesMap.put(name, clazz);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
// load from parent
Class<?> result = findLoadedClass(name);
if (result != null) {
return result;
}
try {
result = findSystemClass(name);
} catch (Exception e) {
// Ignore these
}
if (result != null) {
return result;
}
result = classesMap.get(name);
if (result == null) {
throw new ClassNotFoundException(name);
}
return result;
}
}
我想在代码的其他地方使用它,如下所示:
ClassLoader thisClassLoader = this.getClass().getClassLoader();
((DynamicClassloader) thisClassLoader).defineClass(className, dynClass);
现在我的问题是当我打电话时findSystemClass(name)
对于第 3 方库类,父类加载器会找到该类(因为它位于类路径上)并成为其类加载器。由于父类加载器不知道我的自定义类加载器,因此它实际上已不再使用并且this.getClass().getClassLoader()
无法转换为 DynamicClassLoader。
另一种方法是通过 JVM 参数将我的 ClassLoader 设置为系统 ClassLoader-Djava.system.class.loader=my.DynamicClassloader
。但这给了我一个 StackOverflowError:
...
at de.unisaarland.cs.st.DynamicClassloader.findClass(DynamicClassloader.java:39)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at java.lang.ClassLoader.findSystemClass(ClassLoader.java:916)
at de.unisaarland.cs.st.DynamicClassloader.findClass(DynamicClassloader.java:39)
...
这一定很容易做到,但我现在没有主意了……非常感谢任何帮助!