You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 13:10:32