Java中动态加载jar文件和class文件

概述

  诸如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<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中动态加载jar文件和class文件,布布扣,bubuko.com

时间: 2024-08-02 02:50:16

Java中动态加载jar文件和class文件的相关文章

[转载] Java中动态加载jar文件和class文件

转载自http://blog.csdn.net/mousebaby808/article/details/31788325 概述 诸如tomcat这样的服务器,在启动的时候会加载应用程序中lib目录下的jar文件以及classes目录下的class文件,另外像spring这类框架,也可以根据指定的路径扫描并加载指定的类文件,这个技术可以实现一个容器,容纳各类不同的子应用. Java类由于需要加载和编译字节码,动态加载class文件较为麻烦,不像C加载动态链接库只要一个文件名就可以搞定,但JDK仍

Java_Java中动态加载jar文件和class文件

转自:http://blog.csdn.net/mousebaby808/article/details/31788325 概述 诸如tomcat这样的服务器,在启动的时候会加载应用程序中lib目录下的jar文件以及classes目录下的class文件,另外像spring这类框架,也可以根据指定的路径扫描并加载指定的类文件,这个技术可以实现一个容器,容纳各类不同的子应用. Java类由于需要加载和编译字节码,动态加载class文件较为麻烦,不像C加载动态链接库只要一个文件名就可以搞定,但JDK仍

Java 从Jar文件中动态加载类

由于开发的需要,需要根据配置动态加载类,所以简单测试了一下JAVA动态加载类 定义接口 package loader; public interface HelloIface {     public String hello();          public String sayHi(); } 实现接口 在其他插件类实现此接口,并导出为jar,如D:/tmp/test.jar package loader; public class HelloImpl implements HelloIf

java动态加载jar包,并运行其中的类和方法

动态加载jar包,在实际开发中经常会需要用到,尤其涉及平台和业务的关系的时候,业务逻辑部分可以独立出去交给业务方管理,业务方只需要提供jar包,就能在平台上运行. 下面通过一个实例来直观演示: 第一:定义一个抽象类 AbstractAction (稍后换成接口的实例) [java] view plain copy package com.java.loader; public abstract class AbstractAction { public abstract String actio

关于Android 动态加载 jar 文件

1.1 首先需要了解一点:在Android中可以动态加载,但无法像Java中那样方便动态加载jar 原因:Android的虚拟机(Dalvik VM)是不认识Java打出jar的byte code,需要通过dx工具来优化转换成Dalvik byte code才行.这一点在咱们Android项目打包的apk中可以看出:引入其他Jar的内容都被打包进了classes.dex. 所以这条路不通,请大家注意. 1.2 当前哪些API可用于动态加载 1.2.1 DexClassLoader 这个可以加载j

Android动态加载jar/dex

http://www.cnblogs.com/over140/archive/2011/11/23/2259367.html 前言 在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势.本文对网上Android动态加载jar的资料进行梳理和实践在这里与大家一起分享,试图改善频繁升级这一弊病. 声明 欢迎转载,但请保留文章原始出处:) 博客园:http:/

Android 插件化之动态加载jar

有时候会看到一些应用对应的SDcard里的文件夹里有 ***.jar 等文件,现在明白这些文件大概是用来做应用内自动更新用的. 打比方说,类似eclipse 可以通过预留接口,安装各种插件一样. Android 也可以通过动态加载jar 来实现类似的业务代码更新:(这里所说的jar要通过dx工具来转化成Dalvik byte code,下文会讲到) 注意:首先需要了解一点:在Android中可以动态加载,但无法像Java中那样方便动态加载jar 原因:Dalvik虚拟机如同其他Java虚拟机一样

javaEE:day2-servlet生命周期、提交解决中文乱码、tomcat加载jar包或类文件的顺序

servlet生命周期 生命周期简介: servlet在服务器第一次被请求的时候new出来,并初始化(即init())再调用service方法.这个实在服务器中new出来,然后用HashMap加的,与客户端无关.客户端之后访问只调用这个servlet的service方法. 具体分为4步: 1 构造方法 :服务器在被客户端第一次请求的时候运行 仅在服务器中运行一次 2 init方法:客户端第一次访问服务器的时候在服务器中进行初始化 仅一次.并且可以通过config参数在 web.xml中通过(ke

ReportView动态加载带参数的RDCL文件

在vs里新建一个winform程序"ReportViewTest",在form1中添加一个reportView控件,from1的load事件如下: private void Form1_Load(object sender, EventArgs e) { DataSet ds = new DataSet(); try { ds = getDS(); } catch (Exception) { throw; } Microsoft.Reporting.WinForms.ReportDat