Java动态加载jar及class文件
经常碰到需要动态加载jar及class文件的场景。Java类由于需要加载和编译字节码,动态加载class文件较为麻烦,但JDK仍提供了一整套方法来动态加载jar文件和class文件。
一、动态加载jar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | // 系统类库路径 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文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | // 设置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类了。
分类:
22.问题处理
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!