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

    欢迎指正~~~~~~~ 

  • 相关阅读:
    前端 ---- ajax(2)
    前端 ---- ajax(1)
    前端 ---- 博客项目
    Vue 重复进入相同路由消除警报
    axios和message注册全局变量不一样
    element-ui 的input组件 @keyup.enter事件的添加办法
    前端 ----Express
    MyBatis学习一
    SpringMVC学习一
    JVM学习一
  • 原文地址:https://www.cnblogs.com/sideny/p/3354479.html
Copyright © 2011-2022 走看看