Java可执行JAR运行时如何更新读取自外部配置文件的变量?
问题根源
你当前代码用getClass().getClassLoader().getResourceAsStream(file)读取配置,这个API是从JVM类路径下加载资源文件,你打包ShadowJar的时候,项目里的config.properties已经被打进JAR包内部了,所以程序永远读的是JAR包里固化的配置,和你放在JAR同目录的外部配置文件完全没关系,改外部文件自然不会生效。
修复方案
1. 修改配置读取逻辑
把读取类路径资源的逻辑改成读取文件系统中的外部文件,优先读JAR同目录的config.properties,找不到的话可以兼容读内置默认配置兜底:
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class ReadConfig { String token = ""; String fileName = "config.properties"; Properties prop = new Properties(); public String getToken() throws IOException{ InputStream inputStream = null; try { // 优先读取JAR同目录的外部配置文件 File externalConfig = new File(fileName); if (externalConfig.exists() && externalConfig.isFile()) { inputStream = new FileInputStream(externalConfig); } else { // 兜底读取JAR内置的默认配置 inputStream = getClass().getClassLoader().getResourceAsStream(fileName); } if (inputStream == null) { throw new RuntimeException("找不到配置文件,请将config.properties放在JAR同目录"); } prop.load(inputStream); token = prop.getProperty("token"); } catch (Exception e){ System.out.println("读取配置异常: " + e); } finally { if (inputStream != null) { inputStream.close(); } } return token; } }
2. 打包和分发配置
- 用ShadowJar打包的时候,保留内置的默认
config.properties作为兜底即可,不需要做额外配置 - 发布GitHub Release的时候,把打包好的可执行JAR上传即可,用户只需要把自己填写了token的
config.properties放在JAR的同一目录下,运行java -jar xxx.jar就能读取到外部配置,修改配置后直接重启程序就生效,不需要重新编译打包
3. 原生二进制分发方案(可选)
如果需要不用Java环境就能运行的二进制文件,可以用GraalVM的native-image工具把JAR包编译成对应平台的原生可执行文件,分发的时候直接给用户单个二进制文件+配置文件即可,不需要用户安装JRE。
内容的提问来源于stack exchange,提问作者bashful_creature
相关产品推荐
相关产品推荐

