[英]How to load classes from jar file in correct order
我編寫了一個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中的一個類中的Sublcass並且子類尚未加載時,我得到一個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
的超級A
尚未加載。 同時,類加載器不能知道B
有A
作為它的超類。 因此,類加載器通過在完成B
的類加載之前詢問自己的classLoader.loadClass("A")
來負責加載類。
讓我們假設類加載器不知道A
或B
但它有一個方法來顯式加載由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( ... );
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.