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

如何读取运行jar中引用jar中的文件

1.问题发现

       项目中有个common包资源文件,然后springboot项目引用了common,那么我们要怎么读取这个资源了。这里需要考虑三个场景,idea运行时、common jar独立运行时、springboot引用common后运行时。

2.问题解决

2.1.idea运行时

 ProtectionDomain protectionDomain = LibPaths.class.getProtectionDomain();CodeSource codeSource = protectionDomain.getCodeSource();if (codeSource != null) {String jarPath = codeSource.getLocation().getPath();jarPath = jarPath.replaceFirst("^nested:", "");if(!jarPath.endsWith(".jar")){System.out.println("idea运行时classes路径");}

2.2.common jar运行时 

public static String getUrl(){ProtectionDomain protectionDomain = LibPaths.class.getProtectionDomain();CodeSource codeSource = protectionDomain.getCodeSource();if (codeSource != null) {String jarPath = codeSource.getLocation().getPath();jarPath = jarPath.replaceFirst("^nested:", "");System.out.println("JAR 文件路径: " + jarPath);if(jarPath != null){int index = jarPath.indexOf(".jar");String destDir = jarPath;if(index != -1){destDir = new File(jarPath.substring(0, index+4)).getParent();}if(jarPath.endsWith(".jar")){copyJarCuToOut(jarPath,destDir)}else{System.out.println("idea运行时classes路径");}}
}public static void copyJarCuToOut(String jarPath,String destDir) throws IOException {File file = new File(destDir + File.separator + "test");if(!file.exists()){file.mkdirs();copyResourcesFromJar(jarPath,destDir, true);}else{System.out.println(file.getPath() + "已存在");}
}/*** 将 JAR 中指定路径下的所有文件复制到目标目录** @param jarFilePath   JAR 文件的路径* @param resourcePath  JAR 中的资源路径(例如 "resources/")* @param destDir       目标输出目录* @throws IOException  如果复制过程中出现错误*/
public static void copyResourcesFromJar(String jarFilePath, String resourcePath, String destDir) throws IOException {try (JarFile jarFile = new JarFile(jarFilePath)) {Enumeration<JarEntry> entries = jarFile.entries();while (entries.hasMoreElements()) {JarEntry entry = entries.nextElement();if (entry.getName().startsWith(resourcePath) && !entry.isDirectory() && ( entry.getName().endsWith(".cu") || entry.getName().endsWith(".cu.h"))) {// 构建目标路径Path destPath = Paths.get(destDir + File.separator + entry.getName().substring(resourcePath.length()));// 复制文件try (InputStream is = jarFile.getInputStream(entry);OutputStream os = Files.newOutputStream(destPath)) {byte[] buffer = new byte[1024];int len;while ((len = is.read(buffer)) > 0) {os.write(buffer, 0, len);}}System.out.println("已复制: " + entry.getName() + " 到 " + destPath);}}}
}

2.3.springboot jar运行时  

public static String getUrl(){ProtectionDomain protectionDomain = LibPaths.class.getProtectionDomain();CodeSource codeSource = protectionDomain.getCodeSource();if (codeSource != null) {String jarPath = codeSource.getLocation().getPath();jarPath = jarPath.replaceFirst("^nested:", "");System.out.println("JAR 文件路径: " + jarPath);if(jarPath != null){int index = jarPath.indexOf(".jar");String destDir = jarPath;if(index != -1){destDir = new File(jarPath.substring(0, index+4)).getParent();}if(jarPath.endsWith(".jar")){copyJarCuToOut(jarPath,destDir)}else{System.out.println("idea运行时classes路径");}}
}public static void copyJarCuToOut(String jarPath,String destDir) throws IOException {File file = new File(destDir + File.separator + "test");if(!file.exists()){file.mkdirs();copyResourcesFromMultipleJar(jarPath,destDir, true);}else{System.out.println(file.getPath() + "已存在");}
}/*** 将 JAR 中指定路径下的所有文件复制到目标目录** @param jarFilePath   JAR 文件的路径* @param resourcePath  JAR 中的资源路径(例如 "resources/")* @param destDir       目标输出目录* @throws IOException  如果复制过程中出现错误*/
public static void copyResourcesFromMultipleJar(String jarFilePath, String resourcePath, String destDir) throws IOException {// 1. 分离路径部分String[] parts = jarFilePath.split("/!");if (parts.length < 2) {throw new IllegalArgumentException("无效的嵌套 JAR 路径格式");}// 2. 解析外层 JAR 路径(去掉开头的 / 和 !/)String outerJarPath = parts[0];String innerJarEntry = parts[1].replace("!/", "");System.out.println("###################" + outerJarPath);// 3. 打开外层 JARtry (JarFile outerJar = new JarFile(outerJarPath)) {// 4. 获取内层 JAR 的 EntryJarEntry innerEntry = outerJar.getJarEntry(innerJarEntry);if (innerEntry == null) {throw new FileNotFoundException("内层 JAR 不存在: " + innerJarEntry);}System.out.println("innerJarEntry###################" + innerJarEntry);try (InputStream innerIs = outerJar.getInputStream(innerEntry); JarInputStream innerJar = new JarInputStream(innerIs)) {JarEntry entry;while ((entry = innerJar.getNextJarEntry()) != null) {if (entry.getName().startsWith(resourcePath) && !entry.isDirectory()) {// 构建目标路径Path destPath = Paths.get(destDir + File.separator + entry.getName().substring(resourcePath.length()));// 复制文件try (OutputStream os = Files.newOutputStream(destPath)) {byte[] buffer = new byte[1024];int len;while ((len = innerJar.read(buffer)) > 0) {os.write(buffer, 0, len);}}System.out.println("已复制: " + entry.getName() + " 到 " + destPath);}}}}}

2.4.完整代码

package com.omega.common.lib;import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;public class LibPaths {static {try {// 获取 ProtectionDomain 和 CodeSourceProtectionDomain protectionDomain = LibPaths.class.getProtectionDomain();CodeSource codeSource = protectionDomain.getCodeSource();if (codeSource != null) {String jarPath = codeSource.getLocation().getPath();jarPath = jarPath.replaceFirst("^nested:", "");System.out.println("JAR 文件路径: " + jarPath);if(jarPath != null){int index = jarPath.indexOf(".jar");String destDir = jarPath;if(index != -1){destDir = new File(jarPath.substring(0, index+4)).getParent();}if(jarPath.endsWith(".jar")){copyJarCuToOut(jarPath,destDir, false);}else if(jarPath.endsWith(".jar!/")){copyJarCuToOut(jarPath,destDir, true);}LIB_PATH = destDir + File.separator + "test";}else{System.out.println("JAR 文件路径为空");}} else {System.out.println("无法获取 JAR 路径(可能来自系统类加载器)");}} catch (IOException e) {e.printStackTrace();}}public static void copyJarCuToOut(String jarPath,String destDir, boolean multiple) throws IOException {File file = new File(destDir + File.separator + "test");if(!file.exists()){file.mkdirs();if(multiple){copyResourcesFromMultipleJar(jarPath, "test", file.getPath());}else{copyResourcesFromJar(jarPath, "test", file.getPath());}}else{System.out.println(file.getPath() + "已存在");}}/*** 将 JAR 中指定路径下的所有文件复制到目标目录** @param jarFilePath   JAR 文件的路径* @param resourcePath  JAR 中的资源路径(例如 "resources/")* @param destDir       目标输出目录* @throws IOException  如果复制过程中出现错误*/public static void copyResourcesFromJar(String jarFilePath, String resourcePath, String destDir) throws IOException {try (JarFile jarFile = new JarFile(jarFilePath)) {Enumeration<JarEntry> entries = jarFile.entries();while (entries.hasMoreElements()) {JarEntry entry = entries.nextElement();if (entry.getName().startsWith(resourcePath) && !entry.isDirectory() && ( entry.getName().endsWith(".cu") || entry.getName().endsWith(".cu.h"))) {// 构建目标路径Path destPath = Paths.get(destDir + File.separator + entry.getName().substring(resourcePath.length()));// 复制文件try (InputStream is = jarFile.getInputStream(entry);OutputStream os = Files.newOutputStream(destPath)) {byte[] buffer = new byte[1024];int len;while ((len = is.read(buffer)) > 0) {os.write(buffer, 0, len);}}System.out.println("已复制: " + entry.getName() + " 到 " + destPath);}}}}/*** 将 JAR 中指定路径下的所有文件复制到目标目录** @param jarFilePath   JAR 文件的路径* @param resourcePath  JAR 中的资源路径(例如 "resources/")* @param destDir       目标输出目录* @throws IOException  如果复制过程中出现错误*/public static void copyResourcesFromMultipleJar(String jarFilePath, String resourcePath, String destDir) throws IOException {// 1. 分离路径部分String[] parts = jarFilePath.split("/!");if (parts.length < 2) {throw new IllegalArgumentException("无效的嵌套 JAR 路径格式");}// 2. 解析外层 JAR 路径(去掉开头的 / 和 !/)String outerJarPath = parts[0];String innerJarEntry = parts[1].replace("!/", "");System.out.println("###################" + outerJarPath);// 3. 打开外层 JARtry (JarFile outerJar = new JarFile(outerJarPath)) {// 4. 获取内层 JAR 的 EntryJarEntry innerEntry = outerJar.getJarEntry(innerJarEntry);if (innerEntry == null) {throw new FileNotFoundException("内层 JAR 不存在: " + innerJarEntry);}System.out.println("innerJarEntry###################" + innerJarEntry);try (InputStream innerIs = outerJar.getInputStream(innerEntry); JarInputStream innerJar = new JarInputStream(innerIs)) {JarEntry entry;while ((entry = innerJar.getNextJarEntry()) != null) {if (entry.getName().startsWith(resourcePath) && !entry.isDirectory()) {// 构建目标路径Path destPath = Paths.get(destDir + File.separator + entry.getName().substring(resourcePath.length()));// 复制文件try (OutputStream os = Files.newOutputStream(destPath)) {byte[] buffer = new byte[1024];int len;while ((len = innerJar.read(buffer)) > 0) {os.write(buffer, 0, len);}}System.out.println("已复制: " + entry.getName() + " 到 " + destPath);}}}}}}

http://www.dtcms.com/a/262994.html

相关文章:

  • C++ --- list
  • 《Effective Python》第十一章 性能——使用 timeit 微基准测试优化性能关键代码
  • 分发糖果
  • Spring Boot 集成 tess4j 实现图片识别文本
  • Springboot + vue + uni-app小程序web端全套家具商场
  • Serverless 架构入门与实战:AWS Lambda、Azure Functions、Cloudflare Workers 对比
  • 人工智能参与高考作文写作的实证研究
  • 华为物联网认证:开启万物互联的钥匙
  • 设计模式-观察者模式(发布订阅模式)
  • YOLOv12_ultralytics-8.3.145_2025_5_27部分代码阅读笔记-torch_utils.py
  • 现代JavaScript前端开发概念
  • spring-ai-alibaba官方 Playground 示例
  • 使用pyflink进行kafka实时数据消费
  • 电脑开机加速工具,优化启动项管理
  • 【Unity】MiniGame编辑器小游戏(七)贪吃蛇【Snake】
  • Java项目:基于SSM框架实现的云端学习管理系统【ssm+B/S架构+源码+数据库+毕业论文】
  • 离线环境安装elk及设置密码认证
  • 通过案例来了解let、const、var的区别
  • DAY 47 注意力热图可视化
  • 有些Android旧平台,在Settings菜单里的,设置-电池菜单下,没有电池使用数据,如何处理
  • RK3568平台开发系列讲解:HDMI显示驱动
  • 六自由度按摩机器人 MATLAB 仿真
  • HarmonyOS NEXT仓颉开发语言实战案例:电影App
  • Windows VMWare Centos Docker部署Nginx并配置对Springboot应用的访问代理
  • k8s一键部署tongweb7容器版脚本(by why+lqw)
  • 车辆工程中的压力传感技术:MEMS与薄膜传感器的实战应用
  • 22.安卓逆向2-frida hook技术-app使用非http协议抓不到包解决方式
  • Linux 安装使用教程
  • Pytest自动化测试框架入门?
  • Kafka 核心机制面试题--自问自答