java-java.util.jar库加载jar


前言

最近研究关于classloader,实现对模块的热插拔和类替换等功能。然后意外发现一个用于处理JAR包的官方库。

相关概念

什么是JarUrlConnetion

jarUrlConnection通过Jar协议建立一个访问jar包的连接,可以访问这个jar包内部数据

jar协议格式

jar协议的格式如:jar:{archive-url}!/{entry}。

  • archive-url是文件地址
  • !/是分隔符
  • entry是jar包内部的目录或者文件

示例:

  • 访问远程http服务器
    • 整个jar包。jar:http://www.zsmile.top/test.jar!/
    • jar包内的文件。jar:http://www.zsmile.top/test.jar!/Hello.class
    • jar包内的目录。jar:http://www.zsmile.top/test.jar!/top/smile/
  • 访问本地文件系统
    • 整个jar包。jar:file://E:/test.jar!/
    • jar包内的文件。jar:file://E:/test.jar!/Hello.class
    • jar包内的目录。jar:file://E:/test.jar!/top/smile/

功能

获取JarFile

URL url = new URL("jar:file://E:/test.jar!/");
JarURLConnection conn = (JarURLConnection) url.openConnection();
JarFile jarfile = conn.getJarFile();

遍历JarEntry

Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
System.out.println(jarEntry.getName() + " is directory :" + jarEntry.isDirectory());
}

执行class文件

// 获取class数据流
 InputStream inputStream = jarFile.getInputStream(jarEntry);
 int available = inputStream.available();
 byte[] bytes = new byte[available];
inputStream.read(bytes);

// 借助classloader的defineClass将byte转换成class对象
Class<?> aClass = defineClass("top.zsmile.jvm.classloader.Hello", bytes, 0, bytes.length);

// 通过反射调用方法
Method method = aClass.getMethod("main", String[].class);
method.invoke(null, (Object) null);

Manifest

Manifest mainfest = jarfile.getManifest();

// 获取并遍历属性
 System.out.println("manifest Attributes:");
Attributes mainAttributes = manifest.getMainAttributes();
Set<Map.Entry<Object, Object>> entries = mainAttributes.entrySet();
for (Map.Entry<Object, Object> entry : entries) {
    System.out.println(entry.getKey() + "=>" + entry.getValue());
}

// 获取并遍历entry(不知道怎么用)
Map<String, Attributes> entries1 = manifest.getEntries();
for (Map.Entry<String, Attributes> entry : entries1.entrySet()) {
    System.out.println(entry.getKey() + "=>" + entry.getValue());
}

// 获取主函数
String mainClassName = manifest.getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值