最近在考虑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: 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包。
欢迎指正~~~~~~~
分享到:
相关推荐
通过自定义ClassLoader,实现动态加载apk,jar包功能。
类加载器是Java最强大的特征之一。但是开发者常常忘记类加载组件。类加载器是在运行时负责寻找和加载类...默认状态下,应用程序的每个类由java.lang.ClassLoader加载。因为它可以被继承,所以可以自由地加强其功能。
基于自定义Classloader实现类的动态加载和卸载:需要设计加载和卸载。 基于自定义Classloader实现模块化机制:需要设计模块化机制。 使用xar作为模块,实现xar动态加载和卸载:综合应用前面的内容。 NIO 常规 使用 ...
1):本地编译好的class中直接加载 2):网络加载:java.net.URLClassLoader可以加载url指定的类 3):从jar、zip等等压缩文件加载类,自动解析jar文件找到class文件...而由用户自定义的类加载器所加载的类会被卸载掉!
构建: ./make-jar.sh 要使用,将indexed-classpath.jar添加到类路径并设置-Djava.system.class.loader=org.pantsbuild.classloader.IndexedURLClassLoader 。 添加-verbose:class以查看来自类加载器的调试信息。
类加载器 以下代码是一个自定义类加载器,它从 jar 文件加载类。
ClassLoaderTest 测试自定义的URLClassLoader以加载类 测试如何正确关闭类加载器。 测试如何使用反射关闭JarFile来修复资源泄漏。
主要原因是JVM需要加载rt.jar,不管其中的类是否被classloader加载,第一步整个jar都会被JVM加载到内存当中去,模块化可以根据模块的需要加载程序运行需要的class。 在引入了模块系统之后,JDK 被重新组织成 94 ...
13. 自定义ClassLoader 13 14. double保留两位数的两个方案 18 16. 用户输入输出,文件输入输出范例(1) 19 17.以指定符号分割显示 22 17. 单例模式 22 18. 工厂模式 23 19. 读取配置文件(1) 25 20. 根据libName动态...
打包用于生产的应用程序 ix. 21. 接下来阅读什么 5. IV. Spring Boot特性 i. 22. SpringApplication i. 22.1. 自定义Banner ii. 22.2. 自定义SpringApplication iii. 22.3. 流畅的构建API iv. 22.4. Application...
但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地...
但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地...