当前位置: 首页 > 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.lqws.cn/news/583273.html

相关文章:

  • GitHub Actions 入门指南:从零开始自动化你的开发流程
  • Redis中的缓存击穿、缓存穿透和缓存雪崩是什么?
  • 如何提升 iOS App 全链路体验?从启动到退出的优化调试流程
  • 2025群晖NAS新品:Plus系列性能升级,2.5GbE网络标配成亮点
  • Prompt:提示词工程
  • DDL-8-小结
  • C语言之文件操作详解(文件打开关闭、顺序/随机读写)
  • Apache Doris Profile 深度解析:从获取到分析,解锁查询性能优化密码
  • 离线环境安装elk及设置密码认证
  • ChatGPT、DeepSeek等大语言模型助力高效办公、论文与项目撰写、数据分析、机器学习与深度学习建模等科研应用
  • ffmpeg 安装 windows ubuntu
  • RPC-Client模块
  • ERP系统Bug记录
  • 创客匠人解析强 IP 时代创始人 IP 打造的底层逻辑与破局之道
  • Redis 实现消息队列
  • 如何在Vue3中正确使用ref和reactive?
  • 详解Kafka如何保证消息可靠性
  • 海康相机总是抓取前一帧图像
  • 基于MATLAB的SVM支持向量机的乳腺癌分类方法应用
  • docker安装RabbitMQ,创建RabbitMQ容器
  • Reactor 瞬态错误
  • 企业自建云概念解读|私有云、专有云、混合云、分布式云、企业云
  • go 语言大小写SpecialCase转换
  • window显示驱动开发—全屏模式
  • [论文阅读] Neural Architecture Search: Insights from 1000 Papers
  • Apache Seata < 2.3.0 raft反序列化漏洞
  • Clickhouse源码分析-TTL执行流程
  • 【Debian】1- 安装Debian到物理主机
  • 解决 VS Code Remote-SSH “无法安装 VS Code 服务器“ 错误的完整指南
  • 【RTSP从零实践】3、实现最简单的传输H264的RTSP服务器