Java动态加载jar及class文件

 2023-09-05 阅读 94 评论 0

摘要:经常碰到需要动态加载jar及class文件的场景。Java类由于需要加载和编译字节码,动态加载class文件较为麻烦,但JDK仍提供了一整套方法来动态加载jar文件和class文件。 一、动态加载jar // 系统类库路径 File libPath = new File(jar文件所在路径);// 获取所有

    经常碰到需要动态加载jar及class文件的场景。Java类由于需要加载和编译字节码,动态加载class文件较为麻烦,但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<File> 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类了。

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/999.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息