自定义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了哦。

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

 

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

 

整个源代码如下所示:

/**
 * 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: [email protected]  MSN: [email protected]  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 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);
            }
        }
    }

    /**
     * 
     * 加载JAR文件
     * 
* * @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(); } } /** *
     * 从一个目录加载所有JAR文件
     * 
* * @param path */ public static final void loadJarPath(String path) { List files = new ArrayList(); File lib = new File(path); loopFiles(lib, files); for (File file : files) { loadJarFile(file); } } }

 

在程序中,只要使用上面最后两个方法,就可以加载自定义JAR包和一个目录中的所有JAR包了。

 

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

 

欢迎指正~~~~~~~ 

你可能感兴趣的:(Java)