当前位置: 首页 > article >正文

java打包jar后读取依赖jar包中的文件资源,支持读取jlink打包的模块镜像中读取

java项目通常会打包成jar,jar里面依赖第三方的jar,那如何在我们的程序中读取第三方jar中的资源呢,当然还有一种情况,是从新版jdk通过jlink打包生成的镜像中获取第三方资源

这里提供两种打包方式的获取方法

  1. 普通打包的jar,例如springboot的jar
  2. 模块化打包的程序,例如jlink打包的镜像
		try {
			//普通jar包中获取
			//jar:file:///jar包具体位置!/包中资源具体位置
//			URL url = new URL("jar:file:///D:/maven/repository/org/bytedeco/ffmpeg/6.1.1-1.5.10/ffmpeg-6.1.1-1.5.10-windows-x86_64-gpl.jar!/org/bytedeco/ffmpeg/windows-x86_64-gpl/ffmpeg.exe");
			
			//模块化中获取
			//jrt:/模块名/包中资源具体位置
			URL url = new URL("jrt:/org.bytedeco.ffmpeg.windows.x86_64.gpl/org/bytedeco/ffmpeg/windows-x86_64-gpl/ffmpeg.exe");
			InputStream openStream = url.openStream();
			System.out.println(openStream.available());
			
		} catch (java.lang.Exception e) {
			e.printStackTrace();
		}
		

模块化打包获取第三方jar中资源的另外一种方式

新的jdk支持模块化打包,此时是以jrt协议访问的,同时jdk新增了FileSystem类,可以用来访问第三方jar中的资源

		FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
        //fs.getPath("modules/模块名", "包中资源具体的位置");
        Path imagePath = fs.getPath("modules/org.bytedeco.ffmpeg.windows.x86_64.gpl", "org/bytedeco/ffmpeg/windows-x86_64-gpl/ffmpeg.exe");
        byte[] bytes = null;
		try {
			bytes = Files.readAllBytes(imagePath);
		} catch (IOException e) {
			e.printStackTrace();
		}
        System.out.println(bytes.length);

通用获取资源方法

try {
			String jarPathName = "ffmpeg-6.1.1-1.5.10-windows-x86_64-gpl";
			String jrtModuleName = "org.bytedeco.ffmpeg.windows.x86_64.gpl";
			
			ClassLoader systemClassLoader = App.class.getClassLoader();
			Enumeration<URL> systemResources = systemClassLoader.getResources("META-INF/MANIFEST.MF");
			Iterator<URL> iterator = systemResources.asIterator();
			while (iterator.hasNext()) {
				URL next = iterator.next();
				String path = next.toString();
				
				//ffmpeg-6.1.1-1.5.10-windows-x86_64-gpl是普通jar的路径格式,直接以文件名表示
				//org.bytedeco.ffmpeg.windows.x86_64.gpl是jlink打包镜像中以jrt:协议的路径格式,他其实是路径中的模块名
				//通过动态获取App的所有类和第三方依赖jar,进行过滤,再进行拼接第三方jar中资源的具体路径
				if (path.indexOf(jarPathName) >= 0 || path.indexOf(jrtModuleName) >= 0) {
					String replace = path.replace("META-INF/MANIFEST.MF", "");
					
					//jar:file:///jar包具体位置!/包中资源具体位置
					//jrt:/模块名/包中资源具体位置
					replace = replace + "org/bytedeco/ffmpeg/windows-x86_64-gpl/ffmpeg.exe";
					
					System.out.println(replace);
					
					URL url = new URL(replace);
					InputStream openStream = url.openStream();
					System.out.println("ffmpeg:"+openStream.available());
				}

			}
		} catch (java.lang.Exception e) {
			e.printStackTrace();
		}

通过Main方法类的getClassLoader可以获取当前程序所有依赖类和第三方jar,然后通过过滤得到路径,就能获取jar包或者jlink模块镜像中的资源了


http://www.kler.cn/a/287607.html

相关文章:

  • 牛客题库 21738 牛牛与数组
  • 【HarmonyOS】鸿蒙系统在租房项目中的项目实战(二)
  • 基于 CentOS7.6 的 Docker 下载常用的容器(MySQLRedisMongoDB),解决拉取容器镜像失败问题
  • 动态规划之股票系列
  • 基于Springboot+Vue的中国蛇类识别系统 (含源码数据库)
  • 【Electron】Electron Forge如何支持Element plus?
  • axure9树形元件节点的添加
  • SQL-多表查询
  • 深入理解Java集合:如何使用for增强循环和泛型类型转换
  • 笔记整理—uboot番外(1)命令体系
  • 大佬借助ChatGPT写论文发刊到手软,四个步骤20个顶级学术提示词指令
  • MyBatis-SQL-语句执行流程
  • UE5 UMG UI编辑器工作流
  • mybatis if标签判断字符串是否相等
  • 面试基本内容
  • 【GD32】RT-Thread实时操作系统移植(GD32F470ZGT6)
  • 中介者模式详解
  • Pytorch实现多层LSTM模型,并增加emdedding、Dropout、权重共享等优化
  • Python 爬虫爬取京东商品信息
  • 会赢的!(牛客)
  • 买电脑如何选择显卡?
  • 10、Flink 动态表之更新和追加查询详解
  • 【React】Redux-toolkit 处理异步操作
  • 网络是怎样连接的
  • 数美Android SDK
  • JavaWeb笔记整理11——Nginx反向代理Tomcat