簡體   English   中英

如何以正確的順序從jar文件加載類

[英]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尚未加載。 同時,類加載器不能知道BA作為它的超類。 因此,類加載器通過在完成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( ... );
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM