2013-02-15 66 views
2

我做了一個自定義類加載器,我不知道如何「註冊」它。ClassLoader和Class.forName()

public static void main(String[] args) throws Exception { 
    File   jar = new File("Simple.jar"); 
    FileInputStream fis = new FileInputStream(jar); 
    byte[]   bytes = new byte[(int)jar.length()]; 
    fis.read(bytes); 
    fis.close(); 
    MemoryClassLoader cl = new MemoryClassLoader(); 
    cl.defineClasses(bytes); 

    // 1: Following lines works well 
    cl.findClass ("help.Simple") 
     .getMethod("main", new Class[]{ String[].class }) 
     .invoke(null, (Object)args); 

    // 1: it works well 
    cl.findClass ("help.Simple") 
     .getMethod("main", new Class[]{ String[].class }) 
     .invoke(null, (Object)args); 

    // 2: it works well too 
    Class.forName("help.Simple", true, cl) 
     .getMethod("main", new Class[]{ String[].class }) 
     .invoke(null, (Object)args); 

    // 3: it doesn't work 
    Class.forName("help.Simple") 
     .getMethod("main", new Class[]{ String[].class }) 
     .invoke(null, (Object)args); 
} 

實際的MemoryClassloader更復雜,這裏沒有詳細說明。

該程序的輸出:

Hello, world! 
Hello, world! 
Exception in thread "main" java.lang.ClassNotFoundException: help.Simple 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:186) 
    at loader.MemoryClassLoader.main(MemoryClassLoader.java:76) 

的線 「你好,世界!」由help.Simple.main(String[] args)打印。 類的幫助。簡單的是由我的類加載器正確加載。 但調用它的第三種方式Class.forName()不起作用。 爲什麼以及如何將我用自定義類加載器加載的類添加到由默認系統類加載器加載的「標準」類列表中?

+0

我不認爲它爲該線程設置了類加載器,但它爲您提供了一種輕鬆查詢的方法。所以意圖是能夠寫出:'Thread.currentThread()。getContextClassLoader()。findClass(...)'。 – assylias 2013-02-15 10:00:04

回答

3

Class.forName默認使用加載當前類(包含主方法的類)的類加載器。我認爲在這種情況下使它工作的唯一方法是使用接受另一個類加載器的重載方法。

當你的類加載器自己加載其他類時,它應該可以正常工作。

Class.forName("help.Simple", true, cl) 
+0

你是對的,但我等待另一個迴應。我修改了我的第一個問題 – Aerospace 2013-02-15 10:08:22

+0

如果您的意思是實際使用您的自定義類加載器作爲您的主應用程序類的默認值,我認爲唯一的方法是在啓動jvm時加載它 - 請參閱http://stackoverflow.com/問題/ 3801714 /如何到組 - 我 - 自定義類加載器將要-的默認 – Grim 2013-02-15 10:22:25