gpt4 book ai didi

java - 如何以正确的顺序从 jar 文件加载类

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:46:04 25 4
gpt4 key购买 nike

我编写了一个 Java 类加载器来从 jar 文件加载类。

Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry element = entries.nextElement();
if (element.getName().endsWith(".class")) {
//Class Manipulation via ASM
//Loading class with MyClassloader
}
}

问题是:当我加载一个类时,它是来自同一个 Jar 中的一个类的子类,并且该子类尚未加载,我得到一个 ClassNotFoundException。

例子:

class A extends B{}
Class B{}

因为字母顺序,A类先加载。我得到 B 类的 ClassNotFoundException。此时,B 类未加载。

最佳答案

我假设您的类加载是作为某种推送 类文件执行的。然而,您应该它们。为了解释我的意思,让我们看一个普通 Java 类加载的简短示例:

class Main {
public static void main(String[] args) {
new B();
}
}
class B extends A { }
class A { }

当创建一个new B()时,Main的类加载器基本上执行classLoader.loadClass("B")。此时,B 的父类(super class)A 还没有加载。同时,类加载器无法知道 BA 作为它的父类(super class)。因此,类加载器负责加载类,方法是在 B 的类加载完成之前请求自身 classLoader.loadClass("A")

让我们假设类加载器不知道 AB 但它有一个方法来显式加载它由外部实体接收的类 classLoader.inject(String, byte[])。此调用序列将不会计算:

classLoader.inject("B", bBytes);
classLoader.inject("A", aBytes);

因为在加载 B 时,类加载器还不知道 A

在实现自己的类加载器时,您需要做的是将类存储在某种映射中,并实现类加载器的类加载方法,例如:

protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] bytes = map.get(name);
if (bytes != null) {
return defineClass(name, bytes, 0, bytes.length);
} else {
throw new ClassNotFoundException(name);
}
}

通过允许类加载器确定加载顺序,您可以完全避免这个问题。

更准确地说,您需要分两步进行操作和加载,伪算法看起来像这样:

Enumeration<JarEntry> entries = jarFile.entries();
MyClassLoader classLoader = new MyClassLoader();
// First we generate ALL classes that the class loader is supposed to load.
// We then make these classes accessible to the class loader.
while (entries.hasMoreElements()) {
JarEntry element = entries.nextElement();
if (element.getName().endsWith(".class")) {
// Class Manipulation via ASM
classLoader.addClass( ... );
}
}
// Now that the class loader knows about all classes that are to be loaded
// we trigger the loading process. That way, the class loader can query
// itself about ANY class that it should know.
while (entries.hasMoreElements()) {
JarEntry element = entries.nextElement();
if (element.getName().endsWith(".class")) {
classLoader.loadClass( ... );
}
}

关于java - 如何以正确的顺序从 jar 文件加载类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27201543/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com