自定義ClassLoader,用於加載用戶JAR包

最近在考慮C/S結構程序的軟件自動升級的實現方式,好比QQ、飛信等都自動升級的功能。java

 

自動升級模塊雖然尚未編碼完成,可是思路仍是比較清晰的。oop

 

自動升級過程當中,升級文件的JAR包是專門加載到程序中去的,所以,自定義一個ClassLoader,用於加載用戶JAR包,就很是的重要了。測試

 

應用程序ClassLoader只提供了一個public Class<?> loadClass(String name) throws ClassNotFoundException 方法,沒有提供加載JAR的方法。編碼

 

URLClassLoader提供了一個protected void addURL(URL url)的方法,卻是能夠加載JAR包,但苦於非public的。url

 

經測試發現,AppClassLoader是URLClassLoader的子類。所以,咱們徹底能夠利用URLClassLoader了哦。spa

Java代碼 複製代碼  收藏代碼
  1. URLClassLoader system = (URLClassLoader) ClassLoader.getSystemClassLoader();  
URLClassLoader system = (URLClassLoader) ClassLoader.getSystemClassLoader();

 

這樣,咱們能夠經過反射獲得addURL方法,在程序中加載咱們本身的JAR包了。.net

 

整個源代碼以下所示:code

Java代碼 複製代碼  收藏代碼
  1. /**  
  2.  * Copyright (c) YMCN Team  
  3.  * All rights reserved.  
  4.  */  
  5. package com.aboy.toolkit.util;   
  6.   
  7. import java.io.File;   
  8. import java.lang.reflect.Method;   
  9. import java.net.URL;   
  10. import java.net.URLClassLoader;   
  11. import java.util.ArrayList;   
  12. import java.util.List;   
  13.   
  14. /**  
  15.  * @author obullxl  
  16.  *  
  17.  * email: obullxl@163.com  MSN: obullxl@hotmail.com  QQ: 303630027  
  18.  *  
  19.  * Blog: http://obullxl.iteye.com  
  20.  */  
  21. public final class ClassLoaderUtil {   
  22.     /** URLClassLoader的addURL方法 */  
  23.     private static Method addURL = initAddMethod();   
  24.        
  25.     /** 初始化方法 */  
  26.     private static final Method initAddMethod() {   
  27.         try {   
  28.             Method add = URLClassLoader.class  
  29.                 .getDeclaredMethod("addURL"new Class[] { URL.class });   
  30.             add.setAccessible(true);   
  31.             return add;   
  32.         } catch (Exception e) {   
  33.             e.printStackTrace();   
  34.         }   
  35.         return null;   
  36.     }   
  37.   
  38.     private static URLClassLoader system = (URLClassLoader) ClassLoader.getSystemClassLoader();   
  39.   
  40.     /**  
  41.      * 循環遍歷目錄,找出全部的JAR包  
  42.      */  
  43.     private static final void loopFiles(File file, List<File> files) {   
  44.         if (file.isDirectory()) {   
  45.             File[] tmps = file.listFiles();   
  46.             for (File tmp : tmps) {   
  47.                 loopFiles(tmp, files);   
  48.             }   
  49.         } else {   
  50.             if (file.getAbsolutePath().endsWith(".jar") || file.getAbsolutePath().endsWith(".zip")) {   
  51.                 files.add(file);   
  52.             }   
  53.         }   
  54.     }   
  55.   
  56.     /**  
  57.      * <pre>  
  58.      * 加載JAR文件  
  59.      * </pre>  
  60.      *  
  61.      * @param file  
  62.      */  
  63.     public static final void loadJarFile(File file) {   
  64.         try {   
  65.             addURL.invoke(system, new Object[] { file.toURI().toURL() });   
  66.             System.out.println("加載JAR包:" + file.getAbsolutePath());   
  67.         } catch (Exception e) {   
  68.             e.printStackTrace();   
  69.         }   
  70.     }   
  71.   
  72.     /**  
  73.      * <pre>  
  74.      * 從一個目錄加載全部JAR文件  
  75.      * </pre>  
  76.      *  
  77.      * @param path  
  78.      */  
  79.     public static final void loadJarPath(String path) {   
  80.         List<File> files = new ArrayList<File>();   
  81.         File lib = new File(path);   
  82.         loopFiles(lib, files);   
  83.         for (File file : files) {   
  84.             loadJarFile(file);   
  85.         }   
  86.     }   
  87. }  
/**
 * Copyright (c) YMCN Team
 * All rights reserved.
 */
package com.aboy.toolkit.util;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;

/**
 * @author obullxl
 *
 * email: obullxl@163.com  MSN: obullxl@hotmail.com  QQ: 303630027
 *
 * Blog: http://obullxl.iteye.com
 */
public final class ClassLoaderUtil {
    /** URLClassLoader的addURL方法 */
    private static Method addURL = initAddMethod();
    
    /** 初始化方法 */
    private static final Method initAddMethod() {
        try {
            Method add = URLClassLoader.class
                .getDeclaredMethod("addURL", new Class[] { URL.class });
            add.setAccessible(true);
            return add;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static URLClassLoader system = (URLClassLoader) ClassLoader.getSystemClassLoader();

    /**
     * 循環遍歷目錄,找出全部的JAR包
     */
    private static final void loopFiles(File file, List<File> files) {
        if (file.isDirectory()) {
            File[] tmps = file.listFiles();
            for (File tmp : tmps) {
                loopFiles(tmp, files);
            }
        } else {
            if (file.getAbsolutePath().endsWith(".jar") || file.getAbsolutePath().endsWith(".zip")) {
                files.add(file);
            }
        }
    }

    /**
     * <pre>
     * 加載JAR文件
     * </pre>
     *
     * @param file
     */
    public static final void loadJarFile(File file) {
        try {
            addURL.invoke(system, new Object[] { file.toURI().toURL() });
            System.out.println("加載JAR包:" + file.getAbsolutePath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * <pre>
     * 從一個目錄加載全部JAR文件
     * </pre>
     *
     * @param path
     */
    public static final void loadJarPath(String path) {
        List<File> files = new ArrayList<File>();
        File lib = new File(path);
        loopFiles(lib, files);
        for (File file : files) {
            loadJarFile(file);
        }
    }
}

 

在程序中,只要使用上面最後兩個方法,就能夠加載自定義JAR包和一個目錄中的全部JAR包了。blog

 

經本人測試,上面代碼運行無誤,能正常加載自定義JAR包。ip

 

歡迎指正~~~~~~~ 

相關文章
相關標籤/搜索