如何在运行Spring Boot Jar包时正确引用类路径资源
这个问题的核心原因很明确:当你运行打包好的Spring Boot Jar时,Jar内部的资源(比如BOOT-INF/classes/kafka/somejksfile.jks)是存在于Jar文件中的,并非文件系统上的独立文件。而你的代码里应该是用了FileSystemResource或者直接通过File类来读取这个JKS文件(Eclipse运行时资源在本地文件系统的目录里,所以没问题),导致抛出IllegalStateException提示资源必须在文件系统上。
由于你无法修改代码,我们可以通过将Jar内的资源提取到本地文件系统,然后通过命令行覆盖配置属性指向这个外部文件的方式解决,具体步骤如下:
步骤1:提取Jar内的JKS资源
- 用解压工具(比如WinRAR、7-Zip)打开你的
api-account-info.jar - 导航到
BOOT-INF/classes/kafka/目录,找到somejksfile.jks - 将这个文件复制到本地文件系统的某个目录,比如
C:\my-files\poc\external-kafka-resources\kafka\(注意要保持kafka子目录结构,避免路径匹配问题)
步骤2:修改运行命令,指定外部资源路径
根据你的Kafka配置属性,在命令行中添加系统属性来覆盖JKS文件的路径:
情况1:使用Spring Kafka默认配置属性
如果你的JKS路径是通过spring.kafka.producer.ssl.truststore.location(或对应的consumer属性)配置的,直接在命令行覆盖这个属性:
java -jar -Dspring.profiles.active=dev -Dspring.kafka.producer.ssl.truststore.location=C:\my-files\poc\external-kafka-resources\kafka\somejksfile.jks api-account-info.jar
情况2:使用自定义配置属性
如果你的代码里用的是自定义属性(比如kafka.ssl.truststore.path),替换成对应的属性即可:
java -jar -Dspring.profiles.active=dev -Dkafka.ssl.truststore.path=C:\my-files\poc\external-kafka-resources\kafka\somejksfile.jks api-account-info.jar
补充:关于你原来的命令无效的原因
你之前用的-Dspring.config.location=file:\\C:\my-files\poc\projectName\src\main\resources\没有效果,是因为这个参数是指定Spring配置文件的加载位置,但即使配置文件在外部,配置文件里的JKS路径还是指向classpath:下的资源,依然会遇到Jar内资源无法作为文件访问的问题。我们需要直接覆盖JKS文件的物理路径,而不是配置文件位置。
内容的提问来源于stack exchange,提问作者Thiagarajan Ramanathan

