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

news/2025/2/27 10:38:18

概述

诸如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


http://www.niftyadmin.cn/n/1535948.html

相关文章

在windows下编译scribus

编译的scribus版本是1.35svn版&#xff0c;以前的1.34或者1.33都不能按这个方法编译&#xff08;因为以前的版本基于QT3&#xff0c;而QT3没有支持windows的公开版本&#xff09;。 1.下载软件包 所需软件包列表如下&#xff1a; Scribus 1.35 svn源码&#xff08;svn://scri…

goroutine并发MySQL_golang/goroutine 和 swoole/coroutine 协程性能测试对比

协程的一些特性和优点我就不说了&#xff0c;网上很多文章都讲述的很透彻。协程可以理解为纯用户态的线程&#xff0c;其通过协作而不是抢占来进行切换。相对于进程或者线程&#xff0c;协程所有的操作都可以在用户态完成&#xff0c;创建和切换的消耗更低。开发者可以无感知的…

开源排版软件 Scribus

Scribus是一个开源的排版软件&#xff0c;支持Linux/Unix&#xff0c;MacOS X&#xff0c;OS/2和Windows操作系统。它可以用于制作各种出版物&#xff0c;并且有着良好的版面输出能力。当然&#xff0c;它也有着友好的用户界面。Scribus可以满足各种专业出版物的需求&#xff0…

Angular2.js——数据显示

显示数据&#xff0c;即属性绑定机制把数据显示到用户界面上。 在Angular中最典型的数据显示方式&#xff0c;就是把HTML模板中的控件绑定到Angular组件的属性。 接下来介绍几种数据显示的语法和代码片段。 使用插值表达式显示组件属性 要显示组件的属性&#xff0c;最简单的方…

i37100黑苹果_【台式机】i3-7100 微星 B250M PRO-V GTX 660 10.13.6黑苹果引导_Hackintosh_Clover...

简介i3-7100 处理器微星 B250M PRO-V主板安装黑苹果系统&#xff0c;首先&#xff0c;GTX 660的独显决定了&#xff0c;只能安装10.13.6系统。配置电脑型号 微星 MS-7A74 Modified by dsanke 台式电脑操作系统 Windows 10 专业版 64位 ( DirectX 12 )处理器 英特尔 Core i3-710…

malloc()函数与alloc()函数

C语言跟内存分配方式   &#xff08;1&#xff09; 从静态存储区域分配。内存在程序编译的时候就已经分配好&#xff0c;这块内存在程序的整个运行期间都存在。例如全局变量&#xff0c;static变量。 &#xff08;2&#xff09; 在栈上创建。在执行函数时&#xff0c;函数内局…

HP自动检查html标签是否闭合

function HtmlClose($body) {$strlen_var strlen($body);// 不包含 html 标签if (strpos($body, <) false) {return $body;}// html 代码标记$html_tag 0;// 摘要字符串$summary_string ;/*** 数组用作记录摘要范围内出现的 html 标签* 开始和结束分别保存在 left 和 ri…

java linus技术_【Java架构:基础技术】一篇文章搞掂:Linux

基于CentOS一、安装【暂略】二、使用和登录【赞略】三、使用yumCentOS自带yum&#xff0c;这里暂时不介绍安装方式四、使用yum安装JDK1、检查系统是否有安装open-jdkrpm -qa |grep javarpm -qa |grep jdkrpm -qa |grep gcj如果没有输入信息表示没有安装。如果安装可以使用rpm -…