Maven打包Jar后Java ClassLoader无法找到资源求助
问题排查与解决方案
1. 确认Jar包内资源是否存在
先执行命令检查打包后的Jar实际内容,确认目标资源(文件/目录)是否被正确包含:
jar tf your-shaded-jar-file.jar
如果输出列表中没有你需要的资源,说明打包过程中资源未被纳入,需要调整Maven配置。
2. 修复Maven Shade插件配置
当前Shade插件仅设置了主类,未明确保留资源。添加资源过滤规则并升级插件版本(确保兼容Java 9+):
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <!-- 升级到支持Java 9+的版本 --> <executions> <execution> <goals> <goal>shade</goal> </goals> <configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <!-- 添加过滤规则,确保所有类和资源被打包 --> <filters> <filter> <artifact>*:*</artifact> <includes> <include>**/*.class</include> <include>**/*</include> <!-- 包含所有非class类型资源 --> </includes> </filter> </filters> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>org.swordofsouls.discord.chatexporter.test</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
3. 修正资源加载代码
Jar包中不存在“文件夹”类型的资源,getResourceAsStream("")无法读取空目录,需指定具体资源路径:
// 加载根目录下的config.properties InputStream is = test.class.getClassLoader().getResourceAsStream("config.properties"); // 加载resources目录下的logo.png InputStream is = test.class.getClassLoader().getResourceAsStream("resources/logo.png");
如果需要遍历目录下的所有资源,可结合getResources()和JarURLConnection处理:
Enumeration<URL> urls = test.class.getClassLoader().getResources("resources/"); while (urls.hasMoreElements()) { URL url = urls.nextElement(); if (url.getProtocol().equals("jar")) { JarURLConnection conn = (JarURLConnection) url.openConnection(); JarFile jarFile = conn.getJarFile(); Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); if (entry.getName().startsWith("resources/") && !entry.isDirectory()) { InputStream is = jarFile.getInputStream(entry); // 处理资源文件 } } } }
4. 解决ClassLoader返回null的异常
Java 9+中系统类加载器行为有变化,若运行在模块环境下,可尝试:
- 运行Jar时添加模块参数:
java --add-modules ALL-MODULE-PATH -jar your-shaded-jar.jar
- 优先使用当前类的类加载器(替代系统类加载器):
ClassLoader cl = test.class.getClassLoader(); InputStream is = cl.getResourceAsStream("your-resource-path");
5. 检查Java版本兼容性
确保编译(Maven指定的source/target为9)和运行环境的Java版本一致,避免版本不兼容导致类加载异常。
内容的提问来源于stack exchange,提问作者SwordOfSouls
相关产品推荐
相关产品推荐

