java 运行 加载jar,java运行时加载额外的 jar 包或 class
首先讲下java类加载的顺序
每个类加载器有自己的名字空间,对于同一个类加载器实例来说,名字相同的类只能存在一个,并且仅加载一次。不管该类有没有变化,下次再需要加载时,它只是从自己的缓存中直接返回已经加载过的类引用。
接下来讲如何加载外部jar
首先要有一个工程外的jar包,这里假定有个Test.jar,里面有个com.chentaoqian.test.Test类。
使用系统类加载器,加载一个jar
Java
package com.chentaoqian.classloaderdemo;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
public class MyClassloader {
public static void classLoader(File file, String className, String methodName, Object[] args, Class>[] parameterTypes) {
try {
URL url = file.toURI().toURL();
//得到系统类加载器,利用该加载器加载指定路径下的jar包
URLClassLoader urlClassLoader= (URLClassLoader) ClassLoader.getSystemClassLoader();
Method add = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{ URL.class});
add.setAccessible(true);
add.invoke(urlClassLoader, new Object[] {url});
urlClassLoader.loadClass(className);
Class> c = urlClassLoader.loadClass(className);
//列出所有方法
// Method[] methods = c.getMethods();
// for (Method m : methods) {
// System.out.println(m.getName());
// }
//调用方法
// if (args == null) {
// c.getMethod(methodName, parameterTypes).invoke(c.newInstance());
// } else {
// c.getMethod(methodName, parameterTypes).invoke(c.newInstance(), args);
// }
// urlClassLoader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//无参方法的例子
classLoader(new File("E:\\TestJar.jar"), "com.chentaoqian.test.Test", "sayHi", null, null);
//有参方法的例子
classLoader(new File("E:\\TestJar.jar"), "com.chentaoqian.test.Test", "sayBye", new String[]{"byebye"}, new Class>[]{String.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
packagecom.chentaoqian.classloaderdemo;
importjava.io.File;
importjava.lang.reflect.Method;
importjava.net.URL;
importjava.net.URLClassLoader;
publicclassMyClassloader{
publicstaticvoidclassLoader(Filefile,StringclassName,StringmethodName,Object[]args,Class>[]parameterTypes){
try{
URLurl=file.toURI().toURL();
//得到系统类加载器,利用该加载器加载指定路径下的jar包
URLClassLoaderurlClassLoader=(URLClassLoader)ClassLoader.getSystemClassLoader();
Methodadd=URLClassLoader.class.getDeclaredMethod("addURL",newClass[]{URL.class});
add.setAccessible(true);
add.invoke(urlClassLoader,newObject[]{url});
urlClassLoader.loadClass(className);
Class>c=urlClassLoader.loadClass(className);
//列出所有方法
// Method[] methods = c.getMethods();
// for (Method m : methods) {
// System.out.println(m.getName());
// }
//调用方法
// if (args == null) {
// c.getMethod(methodName, parameterTypes).invoke(c.newInstance());
// } else {
// c.getMethod(methodName, parameterTypes).invoke(c.newInstance(), args);
// }
// urlClassLoader.close();
}catch(Exceptione){
e.printStackTrace();
}
}
publicstaticvoidmain(String[]args){
//无参方法的例子
classLoader(newFile("E:\\TestJar.jar"),"com.chentaoqian.test.Test","sayHi",null,null);
//有参方法的例子
classLoader(newFile("E:\\TestJar.jar"),"com.chentaoqian.test.Test","sayBye",newString[]{"byebye"},newClass>[]{String.class});
}
}
使用jdk自带的classloader,可以正确的加载jar包中的指定class,但如果要加载单独的一个class文件,则会报错。
使用自定义类加载器,加载一个class
通过编写一个类继承自ClassLoader,并重写findClass方法
package com.chentaoqian.classloaderdemo;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
public class MyClassloader2 extends ClassLoader {
private String fileName;
public MyClassloader2(String fileName) {
this.fileName = fileName;
}
@Override
protected Class> findClass(String name) throws ClassNotFoundException {
File file = new File(fileName);
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int len = 0;
while ((len = fis.read()) != -1) {
bos.write(len);
}
byte[] data = bos.toByteArray();
fis.close();
bos.close();
return defineClass(name, data, 0, data.length);
} catch (Exception ex) {
ex.printStackTrace();
}
return super.findClass(name);
}
}
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
packagecom.chentaoqian.classloaderdemo;
importjava.io.ByteArrayOutputStream;
importjava.io.File;
importjava.io.FileInputStream;
publicclassMyClassloader2extendsClassLoader{
privateStringfileName;
publicMyClassloader2(StringfileName){
this.fileName=fileName;
}
@Override
protectedClass>findClass(Stringname)throwsClassNotFoundException{
Filefile=newFile(fileName);
try{
FileInputStreamfis=newFileInputStream(file);
ByteArrayOutputStreambos=newByteArrayOutputStream();
intlen=0;
while((len=fis.read())!=-1){
bos.write(len);
}
byte[]data=bos.toByteArray();
fis.close();
bos.close();
returndefineClass(name,data,0,data.length);
}catch(Exceptionex){
ex.printStackTrace();
}
returnsuper.findClass(name);
}
}
package com.chentaoqian.classloaderdemo;
import java.lang.reflect.Method;
public class ClassloaderTest {
public static void main(String[] args) {
MyClassloader2 myClassloader = new MyClassloader2("E:\\Test.class");
try {
//加载class文件
Class> c = myClassloader.loadClass("com.chentaoqian.test.Test");
if(c != null){
try {
Object obj = c.newInstance();
// Method method = c.getDeclaredMethod("sayHi", null);
Method method = c.getMethod("sayHi", null);
//通过反射调用Test类的say方法
method.invoke(obj, null);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
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
packagecom.chentaoqian.classloaderdemo;
importjava.lang.reflect.Method;
publicclassClassloaderTest{
publicstaticvoidmain(String[]args){
MyClassloader2myClassloader=newMyClassloader2("E:\\Test.class");
try{
//加载class文件
Class>c=myClassloader.loadClass("com.chentaoqian.test.Test");
if(c!=null){
try{
Objectobj=c.newInstance();
// Method method = c.getDeclaredMethod("sayHi", null);
Methodmethod=c.getMethod("sayHi",null);
//通过反射调用Test类的say方法
method.invoke(obj,null);
}catch(Exceptione){
e.printStackTrace();
}
}
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}
}
}
这种方式可以正确加载class文件。需要注意的是:若该class文件使用了extends,则加载会报错,因为父类找不到。
java 运行 加载jar,java运行时加载额外的 jar 包或 class相关推荐
- java 卸载dll_在win7下,卸载Java(TM)6 Update 10时,提示windows Installer程序包有问题。此安装需要的DLL不能运行。...
若卸载重新安装JDK安装目录现jdk1.6.0_17没jre6说明手删除jre6文件夹内容(Your Uninstaller 软件卸载造)第安装JDK(假设版本jdk-6u17-windows-i58 ...
- LIstview滑动时不加载图片,停止时加载!
//参照 http://blog.csdn.net/yy1300326388/article/details/45153813 public class CarWashDistanceAdapter ...
- 【java】【转】Java之classpath
http://www.cnblogs.com/wxf0701/archive/2008/08/23/1274579.html 1.class搜索路径的重要性 理解class搜索路径对所有J ...
- java无法加载主类_java运行显示“找不到或无法加载主类”!
java运行显示"找不到或无法加载主类"!一般都自然想到是环境没配置好.但是 也可能是,绝对路径的问题. 今天一个不会java的朋友也不知道从哪整了一个java文件让我帮忙运行一下 ...
- java -jar命令运行jar包时指定外部依赖jar包
大家都知道一个java应用项目可以打包成一个jar,当然你必须指定一个拥有main函数的main class作为你这个jar包的程序入口.具体的方法是修改jar包内目录META-INF下的MANIFE ...
- Java的加载与执行原理详解 Java程序从编写到最终运行经历了哪些过程
前言 Java程序从编写到最终运行大概可概括为3个阶段:编写.编译.运行阶段. 一.编写阶段 程序员在硬盘某个位置新建一个xxx.java文件 使用记事本或者其他文本编辑器例如EditPlus打开xx ...
- java9 jar hell,Java Jar hell运行时异常
运行单元测试时,我遇到了jar hell的问题. java.lang.RuntimeException: found jar hell in test classpath at org.elastic ...
- JAVA入门级教学之(JAVA程序的加载和运行)
JAVA程序的加载和运行 多思考多动脑(边参考文章最后的示意图,边按步骤理解) 1.JAVA程序的加载和运行包括两个非常重要的阶段: 编译阶段 运行阶段 2.我们先来了解一下什么是编译阶段: 首先,我 ...
- java运行时加音乐_Java运行窗体/程序添加自定义背景音乐
本帖最后由 Jesp 于 2020-7-5 00:50 编辑 前言: 最近实训结束,虽然我的坦克大战项目没有做完美,但是我对付出多少回报多少,这一点上我还是比较满意的,因为很多时间有在玩电脑游戏,只有 ...
最新文章
- 昊天善圈浅谈比特币这个类型区块链应用技术的特点及作用
- Shell编程基入门
- 模板 - 图论 - 树链剖分
- 【译】CREDITS: Peer-to-peer (P2P) network and its components
- 计算机接口配件,最近发布:最新的计算机外部接口计算机主板外部接口简介计算机主板接口简介...
- 3dmax高版本转低版本插件_视频编辑干货资料:低版本打开高版本pr文件
- 【转】C# 温故而知新:Stream篇(—)
- 用css、html编写一个两列布局的网页,名称为css.html ,要求左侧宽度为200px ,右侧自动扩展...
- python多线程详解_Python多线程详解
- phpcms二层栏目下拉和当前栏目高亮
- sencha Touch 2.4 学习之 XTemplate模板
- HDU2006 求奇数的乘积【入门】
- 阿里云服务器如何扩容云盘?
- Ubuntu 更改挂载磁盘权限
- SzNOI语法百题之总目录
- qca956x flash usb
- 【012】SylixOS嵌入式实时操作系统助力中国航天事业
- 明日之后怎么跳过实名认证_明日之后,怎么能跳过教学
- 【转】ASC II 完整码表及简介
- java 线性回归_多元线性回归----Java简单实现
热门文章
- SAP CDS entity 中使用 @readonly 进行访问控制
- 关于 SAP Spartacus 服务器端渲染 SSR 无法使用窗口宽度以进行自适应设计的问题
- SAP Spartacus 和Jerry Sandbox应用Store引用的source字段类型差异
- 快速打开Github某个commit页面的方法
- Angular jasmine单元测试框架spec的运行时数据结构
- Chrome开发者工具Element style里的Computed标签页
- Scala range reverse debug
- 访问SAP C4C Business Configuration工作中心时遇到的错误信息
- 如何判断某ABAP系统的Netweaver后台是否支持AMDP
- 介绍一个好用的日期倒计时工具