java动态打jar包_Java中动态加载jar文件和class文件

本文介绍了如何在Java中动态加载jar文件和class文件。通过修改系统类加载器,利用URLClassLoader的addURL方法可以动态添加jar文件到类路径。对于class文件,可以通过遍历指定目录,加载所有.class文件,并使用Class.forName方法来加载类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

诸如tomcat这样的服务器,在启动的时候会加载应用程序中lib目录下的jar文件以及classes目录下的class文件,另外像spring这类框架,也可以根据指定的路径扫描并加载指定的类文件,这个技术可以实现一个容器,容纳各类不同的子应用。

Java类由于需要加载和编译字节码,动态加载class文件较为麻烦,不像C加载动态链接库只要一个文件名就可以搞定,但JDK仍提供了一整套方法来动态加载jar文件和class文件。

动态加载jar文件

// 系统类库路径

File libPath = new File(jar文件所在路径);

// 获取所有的.jar和.zip文件

File[] jarFiles = libPath.listFiles(new FilenameFilter() {

public boolean accept(File dir, String name) {

return name.endsWith(".jar") || name.endsWith(".zip");

}

});

if (jarFiles != null) {

// 从URLClassLoader类中获取类所在文件夹的方法

// 对于jar文件,可以理解为一个存放class文件的文件夹

Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);

boolean accessible = method.isAccessible();// 获取方法的访问权限

try {

if (accessible == false) {

method.setAccessible(true);// 设置方法的访问权限

}

// 获取系统类加载器

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

for (File file : jarFiles) {

URL url = file.toURI().toURL();

try {

method.invoke(classLoader, url);

LOG.debug("读取jar文件[name={}]", file.getName());

} catch (Exception e) {

LOG.error("读取jar文件[name={}]失败", file.getName());

}

}

} finally {

method.setAccessible(accessible);

}

}

动态加载class文件

// 设置class文件所在根路径

// 例如/usr/java/classes下有一个test.App类,则/usr/java/classes即这个类的根路径,而.class文件的实际位置是/usr/java/classes/test/App.class

File clazzPath = new File(class文件所在根路径);

// 记录加载.class文件的数量

int clazzCount = 0;

if (clazzPath.exists() && clazzPath.isDirectory()) {

// 获取路径长度

int clazzPathLen = clazzPath.getAbsolutePath().length() + 1;

Stack stack = new Stack<>();

stack.push(clazzPath);

// 遍历类路径

while (stack.isEmpty() == false) {

File path = stack.pop();

File[] classFiles = path.listFiles(new FileFilter() {

public boolean accept(File pathname) {

return pathname.isDirectory() || pathname.getName().endsWith(".class");

}

});

for (File subFile : classFiles) {

if (subFile.isDirectory()) {

stack.push(subFile);

} else {

if (clazzCount++ == 0) {

Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);

boolean accessible = method.isAccessible();

try {

if (accessible == false) {

method.setAccessible(true);

}

// 设置类加载器

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

// 将当前类路径加入到类加载器中

method.invoke(classLoader, clazzPath.toURI().toURL());

} finally {

method.setAccessible(accessible);

}

}

// 文件名称

String className = subFile.getAbsolutePath();

className = className.substring(clazzPathLen, className.length() - 6);

className = className.replace(File.separatorChar, '.');

// 加载Class类

Class.forName(className);

LOG.debug("读取应用程序类文件[class={}]", className);

}

}

}

}

完成上述两步操作后,即可使用Class.forName来加载jar中或.class文件包含的Java类了。

时间: 06-15

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值