文档章节

Java 从Jar文件中动态加载类

cloud-coder
 cloud-coder
发布于 2014/12/09 11:47
字数 428
阅读 4224
收藏 81

由于开发的需要,需要根据配置动态加载类,所以简单测试了一下JAVA动态加载类

定义接口

package loader;

public interface HelloIface {

    public String hello();
    
    public String sayHi(String name);

}

实现接口

在其他插件类实现此接口,并导出为jar,如D:/tmp/test.jar

package loader;

public class HelloImpl implements HelloIface{

	@Override
	public String hello() {
		return "hello,JAVA世界";
	}

	@Override
	public String sayHi() {
		return "Hi,JAVA World " + name;
	}
}

动态加载类

import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

public class LoadJar {
	public static void main(String[] args) {
		String classPath = "loader.HelloImpl";// Jar中的所需要加载的类的类名
		String jarPath = "file:///D:/tmp/test.jar";// jar所在的文件的URL

		loadJar1(classPath, jarPath);
		loadClass(classPath);
		loadJar2(classPath, jarPath);
		loadClass(classPath);
	}

	public static void loadJar1(String classPath, String jarPath) {
		ClassLoader cl;
		try {
			// 从Jar文件得到一个Class加载器
			cl = new URLClassLoader(new URL[] { new URL(jarPath) });
			// 从加载器中加载Class
			Class<?> c = cl.loadClass(classPath);
			// 从Class中实例出一个对象
			HelloIface impl = (HelloIface) c.newInstance();
			// 调用Jar中的类方法
			System.out.println(impl.hello());
			System.out.println(impl.sayHi("zhangsan"));
			
			try {
				HelloIface impl2 = (HelloIface) Class.forName(classPath)
						.newInstance();
				System.out.println(impl2.hello());
			} catch (ClassNotFoundException e) {
				System.out.println("非系统加载器加载的JAR,不能通过Class.forName使用");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void loadJar2(String classPath, String jarPath) {
		URLClassLoader urlLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
		Class<URLClassLoader> sysClass = URLClassLoader.class;
		try {
			//改变方法的可见性(即通过反映访问本来不可以访问的方法)
			Method method = sysClass.getDeclaredMethod("addURL", new Class[] { URL.class });
			method.setAccessible(true);
			method.invoke(urlLoader, new URL(jarPath));
			
			Class<?> objClass = urlLoader.loadClass(classPath);
			Object instance = objClass.newInstance();
			Method method2 = objClass.getDeclaredMethod("sayHi", new Class[]{ String.class});
			System.out.println(method2.invoke(instance, "zhangsan"));
			
			HelloIface impl2 = (HelloIface) Class.forName(classPath).newInstance();
			System.out.println(impl2.hello());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void loadClass(String classPath){
		try {
			HelloIface impl2 = (HelloIface) Class.forName(classPath)
					.newInstance();
			System.out.println(impl2.hello());
		} catch (Exception e) {
			System.out.println("非系统加载器加载的JAR,不能通过Class.forName使用");
		}
	}
}


© 著作权归作者所有

共有 人打赏支持
cloud-coder
粉丝 248
博文 194
码字总数 141537
作品 0
广州
架构师
私信 提问
加载中

评论(4)

iehyou
iehyou
依赖其他jar太多的话,也是一个麻烦事,不知道你们是不是只是调用单独的jar
cloud-coder
cloud-coder

引用来自“雨秋”的评论

可以研究一下动态加载jar文件。
有相关的代码样例(加载jar文件的),可以分享一下
壹城
壹城
可以研究一下动态加载jar文件。
jiejiecool
jiejiecool
我刚入职,我们系统也有一个api,提供插件,没明白机制,看到你的文章恍然大悟,原来使用的动态类加载
java classloader 过程

jvm classLoader architecture : a, Bootstrap ClassLoader/启动类加载器 主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作. b, Extension ClassLoader/扩......

Idiot_s_Sky
2014/01/19
0
0
Java核心机制:反射机制的原理及应用方法

一、java的核心机制 java有两种核心机制:java虚拟机(JavaVirtual Machine)与垃圾收集机制(Garbage collection): 1、Java虚拟机:是运行所有Java程序的抽象计算机,是Java语言的运行环境,在...

Java架构资源分享
2018/11/25
0
0
阿里P8技术心得:java反射机制的核心原理

一、java的核心机制 java有两种核心机制:java虚拟机(JavaVirtual Machine)与垃圾收集机制(Garbage collection): 1、Java虚拟机:是运行所有Java程序的抽象计算机,是Java语言的运行环境,在...

Java架构
2018/11/25
0
0
深入分析Java ClassLoader原理

一、什么是ClassLoader? 大家都知道,当我们写好一个Java程序之后,不是管是CS还是BS应用,都是由若干个.class文件组织而成的一个完整的Java应用程序,当程序在运行时,即会调用该程序的一个...

5W1H-
2013/05/27
0
2
JVM自定义类加载器加载指定classPath下的所有class及jar

一、JVM中的类加载器类型   从Java虚拟机的角度讲,只有两种不同的类加载器:启动类加载器和其他类加载器。   1.启动类加载器(Boostrap ClassLoader):这个是由c++实现的,主要负责JAVAH...

Ala6
2018/10/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

intellJ IDEA搭建java+selenium自动化环境(maven,selenium,testng)

1.安装jdk1.8; 2.安装intellJ; 3.安装maven; 3.1 如果是单前用户,配置用户环境变量即可,如果是多用户,则需配置系统环境变量,变量名为MAVEN_HOME,赋值D:\Application\maven,往path中...

不最醉不龟归
51分钟前
2
0
聊聊ShenandoahGC的Brooks Pointers

序 本文主要研究一下ShenandoahGC的Brooks Pointers Shenandoah Shenandoah面向low-pause-time的垃圾收集器,它的GC cycle主要有 Snapshot-at-the-beginning concurrent mark包括Init Mark(P......

go4it
昨天
2
0
Makefile通用编写规则

#简单实用的Makefile模板: objs := a.o b.o test:$(objs) gcc -o test $^ # .a.o.d .b.o.d dep_files := $(foreach f,$(objs),.$(f).d) dep_files := $(wildcard $(dep_files)) ifneq ($(d......

shzwork
昨天
1
0
《万历十五年》的读后感作文4000字

《万历十五年》的读后感作文4000字: 万历十五年,即1587年,距今已过去432年。在明朝276的历史中,这一年很平淡,并没有什么特别之处。黄仁宇的《万历十五年》一书,有别于其他的历史叙述方...

原创小博客
昨天
1
0
vue组件系列4、Table封装下

知道了slot 怎么用,才可以理解table这样封装的原因 table插件部分 <template> <div> <!-- 关键字部分 --> <div class="pre_search" v-show="show_key"> <label>关键字:......

轻轻的往前走
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部