使用Maven Assembly插件构建Spring Boot可执行Jar时遇文件找不到异常
dataload.properties的问题 嘿,我来帮你搞定这个头疼的配置文件找不到的问题!你遇到的org.springframework.beans.factory.BeanDefinitionStoreException本质上就是Spring在类路径里找不到你的dataload.properties,这大概率和你用Maven Assembly插件打包的方式,以及外部化配置的路径设置没匹配上有关。
咱先拆解下问题根源:要么是你打包时没把配置文件放到Jar外面的指定位置,要么是Spring Boot还在默认从Jar内部的类路径找文件,没去读外部的配置。下面给你几个靠谱的解决步骤:
第一步:修正Maven Assembly插件配置,把配置文件放到外部目录
你需要确保Assembly插件把dataload.properties打包到Jar同级的config目录(或者你指定的外部目录),而不是塞进Jar包内部。给你一个参考的assembly descriptor配置:
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd"> <id>executable-jar-with-external-config</id> <formats> <format>jar</format> </formats> <includeBaseDirectory>false</includeBaseDirectory> <!-- 打包项目依赖和自身代码到Jar --> <dependencySets> <dependencySet> <outputDirectory>/</outputDirectory> <useProjectArtifact>true</useProjectArtifact> <unpack>true</unpack> <scope>runtime</scope> </dependencySet> </dependencySets> <!-- 把配置文件复制到Jar同级的config目录 --> <fileSets> <fileSet> <directory>src/main/resources</directory> <outputDirectory>config</outputDirectory> <includes> <include>dataload.properties</include> </includes> </fileSet> </fileSets> </assembly>
配置完后,执行mvn clean package assembly:single打包,打包完成后检查Jar所在目录,应该能看到一个config文件夹,里面就有dataload.properties。
第二步:让Spring Boot正确加载外部配置文件
现在配置文件已经在外部了,得让Spring Boot知道去哪找它,有几种方式可选:
方式1:启动Jar时通过命令行参数指定配置位置
这是最灵活的方式,不用改代码,启动时直接指定:
# 指定整个config目录,Spring会自动扫描里面的配置文件 java -jar your-app.jar --spring.config.location=./config/ # 或者精准指定单个配置文件 java -jar your-app.jar --spring.config.location=./config/dataload.properties
注意:./config/是相对路径,指的是Jar所在的当前运行目录下的config文件夹,如果是绝对路径直接写全路径就行,比如/opt/app/config/。
方式2:在启动类里用@PropertySource指定外部路径
如果不想每次启动都加参数,可以在你的BatchJobsStarter类里加上注解,注意要加file:前缀表示加载外部文件:
@SpringBootApplication @PropertySource(value = "file:./config/dataload.properties", ignoreResourceNotFound = false) public class BatchJobsStarter { public static void main(String[] args) { SpringApplication.run(BatchJobsStarter.class, args); } }
这里ignoreResourceNotFound=false会强制检查文件是否存在,调试阶段很有用,上线后可以根据需求改成true。
方式3:利用Spring Boot的默认扫描规则
其实Spring Boot默认会自动扫描几个位置的配置文件,其中就包括Jar同级的config目录,以及当前运行目录。所以只要你把dataload.properties放到Jar同级的config文件夹里,不用额外配置,Spring Boot就能自动加载它。不过前提是你没在代码里硬编码死类路径加载。
最后要检查的几个点
- 打包后一定要确认
dataload.properties确实在Jar外面的config目录里,而不是被打进Jar包内部了(可以用解压工具打开Jar看看里面有没有这个文件) - 如果用相对路径,要确保Jar的运行目录和你预期的一致,比如你在
/opt/app目录下运行Jar,那./config/就是/opt/app/config/ - 如果你同时有Jar内部和外部的同名配置文件,Spring Boot会优先加载外部的,这点要注意避免配置冲突
内容的提问来源于stack exchange,提问作者Yakiv

