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

Spring Boot构建Fat JAR遇Jersey资源扫描文件不存在错误

搞定Spring Boot Fat Jar里Jersey启动的FileNotFoundException问题

嘿,我一眼就看出问题出在哪了——你用的Jersey版本(2.25.1)根本不兼容Spring Boot Fat Jar的目录结构!Spring Boot把编译好的类都塞在BOOT-INF/classes下面,但旧版Jersey的资源扫描器完全搞不懂这种嵌套在Jar里的路径,所以才会报找不到文件的错。

下面给你几个靠谱的解决办法,按优先级来:

1. 优先升级Jersey到兼容版本

Spring Boot 1.5.12.RELEASE对应的Jersey,只要升级到2.26-b03及以上版本,这个问题就直接解决了——这个版本专门修复了Fat Jar资源扫描的bug。你只需要在POM里加个版本属性统一覆盖就行:

<properties>
    <jersey.version>2.26-b03</jersey.version>
</properties>

2. 要是没法升级,就换个扫描器

如果因为项目限制不能升级Jersey,那咱们就手动接管Jersey的资源注册,用Spring的扫描器代替Jersey自带的。写个配置类就行:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;

@Configuration
public class JerseyConfig {

    @Bean
    public ResourceConfig jerseyResourceConfig() {
        ResourceConfig config = new ResourceConfig();
        // 先关掉Jersey自己的自动扫描
        config.property(ServerProperties.PROVIDER_SCANNING_RECURSIVE, false);
        
        // 用Spring的扫描器手动找所有Jersey资源和提供者
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            // 把这里换成你自己的Jersey资源包路径
            String[] packages = {"com.yourteam.resources", "com.yourteam.providers"};
            for (String pkg : packages) {
                String pattern = "classpath*:" + pkg.replace('.', '/') + "/**/*.class";
                org.springframework.core.io.Resource[] resources = resolver.getResources(pattern);
                for (org.springframework.core.io.Resource resource : resources) {
                    String className = resource.getFilename().replace(".class", "");
                    String fullClassName = pkg + "." + className;
                    config.register(Class.forName(fullClassName));
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("注册Jersey资源失败", e);
        }
        
        return config;
    }
}

3. 清理一下Maven插件的多余配置

看你的POM里spring-boot-maven-plugin加了requiresUnpack配置,除非那个my.com:myArtifact依赖真的需要解压才能用,不然这个配置可以删掉——Jersey本身不需要解压,留着反而可能添乱:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

4. 顺便解决依赖版本不一致的问题

看你的依赖树里,jersey-apache-connector用的是2.17版本,和其他Jersey组件的2.25.1不统一,这很容易出兼容性问题。建议在POM里加个dependencyManagement统一所有Jersey的版本:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey</groupId>
            <artifactId>jersey-bom</artifactId>
            <version>${jersey.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

最后说下为啥会出这问题

Spring Boot的Fat Jar是嵌套结构:应用类在BOOT-INF/classes,依赖Jar在BOOT-INF/lib。但旧版Jersey(2.25.1及以下)的扫描器只能识别传统的Jar路径(比如file:/xxx.jar!/),根本看不懂file:/xxx.jar!/BOOT-INF/classes这种嵌套路径,所以才会报找不到文件的错。


内容的提问来源于stack exchange,提问作者Chad Van De Hey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:24:06