Spring Boot应用部署Linux服务器时无法找到SPI实现
解决Spring Boot SPI部署Linux后找不到实现的问题
核心问题拆解
你在manifest.mf里加Class-Path: META-INF/services/没用,因为这个属性是用来指定外部Jar或目录的类路径,根本不是Jar包内部的资源路径。Spring Boot打包成fat jar后,SPI的META-INF/services配置文件得被正确放到Jar根目录,还要保证类加载器能正常访问到。
基于Manifest.mf的具体解决步骤
1. 先确认SPI配置文件的位置
你的META-INF/services目录必须放在项目的src/main/resources下面,这样打包时才会自动被放到Jar的根目录里。如果是多模块项目,要检查SPI实现所在模块的resources目录下,确实有这个文件夹,且里面的配置文件(文件名是接口全限定名,内容是实现类全限定名)没写错。
2. 配置打包插件,保留Manifest自定义配置+正确打包SPI资源
Maven项目修改pom.xml
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <!-- 保留自定义Manifest内容,不要在这里加内部的META-INF/services路径 --> <manifest> <addClasspath>true</addClasspath> <!-- 只有当SPI实现在外部Jar时,才在这里配置Class-Path,比如:<classpathPrefix>lib/</classpathPrefix> --> </manifest> <!-- 确保META-INF/services不被打包过滤 --> <resources> <resource> <directory>src/main/resources</directory> <filtering>false</filtering> <includes> <include>META-INF/services/**</include> </includes> </resource> </resources> </configuration> </plugin> </plugins> </build>
Gradle项目修改build.gradle
springBoot { mainClass = 'com.yourpackage.YourApplication' manifest { // 仅当SPI实现在外部Jar时,才配置Class-Path,比如:attributes 'Class-Path': 'lib/your-spi-jar.jar' } } sourceSets { main { resources { include 'META-INF/services/**' } } }
3. 处理外部Jar形式的SPI实现(如果适用)
如果你的SPI实现不在当前Spring Boot Jar内部,而是独立的外部Jar,那manifest.mf里的Class-Path要指向这个外部Jar的相对路径。比如外部Jar放在Spring Boot Jar同目录的lib文件夹下,Manifest里要这么写:
Class-Path: lib/your-spi-implementation.jar
注意:路径是相对于Spring Boot Jar的运行目录,不是Jar内部的路径。
4. 打包后验证
打包完成后,解压Jar包检查:确认META-INF/services在Jar根目录下,且配置文件内容正确。也可以在Linux服务器上用java -jar your-app.jar -verbose:class查看类加载日志,确认SPI实现类是否被加载。
内容的提问来源于stack exchange,提问作者Muddassir Rahman
相关产品推荐
相关产品推荐

