我的自定义 java ClassLoader 加载一个 class,但 clazz.getClassLoader() 是 myClassLoader.getParent(),而不是 myClassLoader
My custom java ClassLoader loads a class, but clazz.getClassLoader() is myClassLoader.getParent(), not myClassLoader
我有一个 classloader,它看起来像这样:
@Override
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if(isExcluded(name)) return super.loadClass(name, resolve);
// irrelevant... it always returns above
InputStream s = getResourceAsStream(name.replace('.', '/') + ".class");
if(s == null) throw new ClassNotFoundException(name);
ClassReader reader;
try {
reader = new ClassReader(s);
} catch(IOException e) {
throw new RuntimeException(e);
}
ClassWriter writer = new ClassWriter(Opcodes.ASM4);
ClassVisitor v = new RemappingClassAdapter(writer, remapper);
reader.accept(v, 0);
byte[] bytes = writer.toByteArray();
Class<?> c = defineClass(name, bytes, 0, bytes.length);
if(resolve) {
resolveClass(c);
}
return c;
}
那我做
MyClassLoader loader = new MyClassLoader(Main.class.getClassLoader());
Class<?> c = loader.loadClass(className, true); // also tried false, and loader.loadClass(className)
c.getClassLoader(); // AppClassLoader instead of MyClassLoader, why?
Method m = c.getDeclaredMethod(methodName);
return m.invoke(c.newInstance());
不应该由 classloader 加载的 class,它的 classloader 是 classloader 吗?我想要这个的原因是,我正在加载的 class 引用的任何 class (className
),我希望它也被 MyClassLoader 加载。如果那不是任何事情的运作方式,那么它是如何运作的?我该如何做我想做的事?
事实上,我没有使用过自定义 ClassLoader,但据我了解,在这些 ClassLoader 对象的级别上,它们通过父/子关系相互关联。
这意味着当一个 ClassLoader 要加载一个 class 时,它首先询问它的父 ClassLoader 它是否可用,在这种情况下它加载它。如果父 ClassLoader 无法加载它,则将请求委托给下一个父类,直到到达 BootStrapClassLoader。如果父类加载器的 none 可以加载 class,当前的 class 加载器将尝试从其可用路径加载它。找不到它会导致 ClassNotFoundException。
当 class 加载器委托给其父加载器时,与加载的 class(由 Class.getClassLoader()
返回)关联的 class 加载器是父加载器。那是因为父加载器是调用 defineClass()
.
的加载器
defineClass()
是关键方法;它调用 JVM 中的一些本机代码来创建 class 并将其关联到其 class 加载程序。
我有一个 classloader,它看起来像这样:
@Override
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if(isExcluded(name)) return super.loadClass(name, resolve);
// irrelevant... it always returns above
InputStream s = getResourceAsStream(name.replace('.', '/') + ".class");
if(s == null) throw new ClassNotFoundException(name);
ClassReader reader;
try {
reader = new ClassReader(s);
} catch(IOException e) {
throw new RuntimeException(e);
}
ClassWriter writer = new ClassWriter(Opcodes.ASM4);
ClassVisitor v = new RemappingClassAdapter(writer, remapper);
reader.accept(v, 0);
byte[] bytes = writer.toByteArray();
Class<?> c = defineClass(name, bytes, 0, bytes.length);
if(resolve) {
resolveClass(c);
}
return c;
}
那我做
MyClassLoader loader = new MyClassLoader(Main.class.getClassLoader());
Class<?> c = loader.loadClass(className, true); // also tried false, and loader.loadClass(className)
c.getClassLoader(); // AppClassLoader instead of MyClassLoader, why?
Method m = c.getDeclaredMethod(methodName);
return m.invoke(c.newInstance());
不应该由 classloader 加载的 class,它的 classloader 是 classloader 吗?我想要这个的原因是,我正在加载的 class 引用的任何 class (className
),我希望它也被 MyClassLoader 加载。如果那不是任何事情的运作方式,那么它是如何运作的?我该如何做我想做的事?
事实上,我没有使用过自定义 ClassLoader,但据我了解,在这些 ClassLoader 对象的级别上,它们通过父/子关系相互关联。 这意味着当一个 ClassLoader 要加载一个 class 时,它首先询问它的父 ClassLoader 它是否可用,在这种情况下它加载它。如果父 ClassLoader 无法加载它,则将请求委托给下一个父类,直到到达 BootStrapClassLoader。如果父类加载器的 none 可以加载 class,当前的 class 加载器将尝试从其可用路径加载它。找不到它会导致 ClassNotFoundException。
当 class 加载器委托给其父加载器时,与加载的 class(由 Class.getClassLoader()
返回)关联的 class 加载器是父加载器。那是因为父加载器是调用 defineClass()
.
defineClass()
是关键方法;它调用 JVM 中的一些本机代码来创建 class 并将其关联到其 class 加载程序。