zoukankan      html  css  js  c++  java
  • 自定义ClassLoader,用于加载用户JAR包

    最近在考虑C/S结构程序的软件自动升级的实现方式,比如QQ、飞信等都自动升级的功能。

    自动升级模块虽然还没有编码完成,但是思路还是比较清晰的。

    自动升级过程中,升级文件的JAR包是专门加载到程序中去的,因此,自定义一个ClassLoader,用于加载用户JAR包,就非常的重要了。

    应用程序ClassLoader只提供了一个public Class<?> loadClass(String name) throws ClassNotFoundException 方法,没有提供加载JAR的方法。

    URLClassLoader提供了一个protected void addURL(URL url)的方法,倒是可以加载JAR包,但苦于非public的。

    经测试发现,AppClassLoader是URLClassLoader的子类。因此,我们完全可以利用URLClassLoader了哦。

    Java代码 复制代码 收藏代码
    1. URLClassLoader system = (URLClassLoader) ClassLoader.getSystemClassLoader();  
    URLClassLoader system = (URLClassLoader) ClassLoader.getSystemClassLoader();

    这样,我们可以通过反射得到addURL方法,在程序中加载我们自己的JAR包了。

    整个源代码如下所示:

    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包了。

    经本人测试,上面代码运行无误,能正常加载自定义JAR包。

    欢迎指正~~~~~~~ 

  • 相关阅读:
    BZOJ5212 ZJOI2018历史(LCT)
    BZOJ5127 数据校验
    253. Meeting Rooms II
    311. Sparse Matrix Multiplication
    254. Factor Combinations
    250. Count Univalue Subtrees
    259. 3Sum Smaller
    156. Binary Tree Upside Down
    360. Sort Transformed Array
    348. Design Tic-Tac-Toe
  • 原文地址:https://www.cnblogs.com/sideny/p/3354479.html
Copyright © 2011-2022 走看看