Java中动态载入jar文件和class文件
2023-09-27 14:25:17 时间
概述
诸如tomcat这种server,在启动的时候会载入应用程序中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<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类了。
相关文章
- java设计模式-菜鸟网络
- nohup java -Dserver.port=8087 -Dspring.config.location=application-generic.yml -jar ${APP_HOME}/${APP_NAME} >/dev/null 2>&1
- Java Web项目缺少jsp、servlet jar包
- Java的jar文件安装成windows 服务
- Idea:Java文件打包可执行的JAR文件,并指定JDK编译版本
- JAVA单元测试框架-14-实现TestNG失败案例重跑
- 2022年目前最新上千道Java面试题,刷完你不进大厂谁进大厂
- 还在担心 2022 的秋招吗, 啃透这份 Java 架构知识点笔记,薪资必涨。
- java中关于如何运行jar格式程序的说明
- java整理软件--- Java OCR 图像智能字符识别技术,可识别中文,但是验证码不可以识别...已测识别中文效果很好
- java方法特点
- 将java的jar包作为windows的服务来启动
- Java学习-039-源码 jar 包的二次开发扩展实例(源码修改)
- java.util.concurrent解析——FutureTask源码解析
- Java_Java中动态加载jar文件和class文件
- Java多线程之Join方法阻塞线程
- jar包/class文件如何快速反编译成java文件---- jd-gui
- Java GC
- 加载依赖的jar包在命令行编译和运行java文件
- Java多媒体编程应用
- Java线程池详解
- 用JSmooth制作java jar文件的可运行exe文件教程【图文】
- JAVA class 编译jar。 控制台使用jar
- JAVA array,map 转 json 字符串
- Java使用jxl.jar操作excel,合并单元格等
- 将项目打成jar包执行 在liunx上执行 java -xx.jar
- MacBook Java开发环境的配置
- Delphi XE7的安卓程序如何调用JAVA的JAR,使用JAVA的类?