Runtime.getRuntime().exec执行jar包修改配置文件并替换问题记录
微服务结构:子工程依赖父工程,父工程向子工程提供统一配置及公用类,多个子工程依赖同一个父工程。
角色定位:这个父工程,是整个应用系统的基础设施。这个基础设施,不是简单的抽取微服务的配置等,还包括了对第三方的组件集成与优化,减少子工程的配置文件,最好达到子工程只需要提供多种环境的yml文件即可而不需要额外的配置文件等。
结构依赖图示:
为了达到减少子工程的配置文件目的,把子工程所需要的scm.properties配置文件移到父工程中。
这带来了一个问题,每个子工程的scm.properties文件都是不同的,抽取到父工程时,必然涉及到子工程修改父工程的配置文件,但是,父工程现在已经作为一个jar包已经依赖到子工程中去。通过`Properties`修改的方式并不能达到如期目标,因为jar包中的文件已经是只读的,生成新的`scm.properties`文件是在子工程的目录下。
换另一种思路,就是在系统启动时,紧接着将子工程的`scm.properties`文件通过`jar uvf 带绝对路径的jar包 -C 带绝对路径的子包目录 scm.properties`命令替换父工程的scm.properties文件。
问题一:在本微服务应用中,通过`Runtime.getRuntime().exec`调用上述`jar`命令无效
原因:`Runtime.getRuntime().exec(jar)`的执行与本微服务应用是在通过一个jvm环境中。会看到虽然jar命令执行成功已经被输出到日志中,但实际应用还是启动不起来。原因就是该jar包已经被加载到jvm中。验证是这一原因的方式:把jar命令语句中的带绝对路径的jar包改成不带路径的jar包,系统仍然由读取到scm.properties中的值不对,而报错启动不起来,且输出日志中,也看到jar执行成功的v命令参数信息`正在添加: scm.properties(输入 = 157) (输出 = 145)(压缩了 7%)`。
解决方式:将`Runtime执行jar命令`的调用放到一个独立于本微服务应用中的Java类中,如:
/**
* 以main方法独立执行系统调用命令
*
*
* @author: 18109115
* @since: 1.0
* @see [相关类/方法](可选)
*/
public class ReplaceInstructionJar {
public static void main(String[] args) {
String jarName = args[0];
String directory = args[1];
System.out.println(" input param " + jarName + " , " + directory);
String cmd = "jar uvf " + jarName + " -C " + directory + " scm.properties";
String[] cmds = {"cmd", "/c", cmd};
try {
Process process = Runtime.getRuntime().exec(cmds);
InputStream stream = process.getInputStream();
InputStreamReader isr = new InputStreamReader(stream, "GBK");
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
process.waitFor();
System.out.println(" end jar command. ");
} catch (Exception e) {
System.out.println(e);
}
}
}
然后在原来调用jar命令的地方改成`Runtime调用执行java命令,独立运行main方法的方式执行jar包修改并更新配置文件 `的方式(这个java文件必须是已经javac过的,我测试时,是用的断点设置,然后再另一个项目中main启动方式,道理是一样的,使用java命令的时候,别忘记`-classpath `指定该java文件所在的路径):
总结:
其实,最简单的方式就是在子工程添加scm.properties文件,这样我司中间件ShardRedis就不会报错,我司中间件ShardRedis使用时是强依赖scm.properties的。不过,为了追寻子工程简化配置文件,才有了jar包修改配置文件的方式。另一种方式Jar包加载卸载没研究过,欢迎有想法并实际应用过的小伙伴私信我或在底下留言,共同进步。
本文地址:https://blog.csdn.net/qq_21949545/article/details/110224329
下一篇: PHP中域名绑定