1、背景
最近接触了一个名词叫嵌入式安装,一开始不是很懂,后来想想以前玩单片机的场景,捉摸着嵌入式安装应该就是个软件一键部署的安装场景。当前我们安装一个软件一般是要经过下载软件包、解压、配置、启动等步骤,如果有对应的软件管理app,也许可以做到一键安装,不用手动操作那几个步骤。但是嵌入式安装本身就是一种极精简的安装模式,如果为了一键安装再引入一个其它管理工具,那么就失去了其意义。
jvm具有很好的移植性,而且它属于底层开发环境,很多机器都有。因此可以通过java代码控制软件安装部署的流程,并将项目打成jar包,最后通过简单的java -jar命令实现一键部署。
2、实现思路
1)将软件包放入项目中,跟随项目一块打成jar包。
2)编辑安装和操作脚本,安装脚本用于操作项目的移动、配置文件的更改、软件启动等。操作脚本则用于测试软件是否正确安装获取执行一些初始化操作等。(具体的可以根据自己的实际需求来写)
3)在运行jar包的时候先去解压jar包,然后再调用安装脚本,最后调用操作脚本。
3、代码框架
项目结构如下
代码很简单,只有一个Main类,其用于控制整个安装的流程,具体的安装细节则由install.sh和operate.sh两个文件控制。这样后期我们只需要更改两个脚本和待安装的软件包就行。而且jar包还有一个特性就行可以用压缩软件打开,以后即使没有开发工具,但是也可以将编辑好的脚本和软件包替换到jar里面。这增加了该项目的可复用性。下面是Main的核心方法:
import java.io.*;
/**
* @ClassName Main
* @Description: 嵌入式封装入口
* @Author wangyongtao
* @Date 2023/2/18 9:27
* @Version 1.0
**/
public class Main {
public static void main(String[] args) {
System.out.println("嵌入式部署开始...");
InputStream in = null;
InputStream error = null;
try {
//1、解压
String basePath = Main.class.getProtectionDomain().getCodeSource().getLocation().getFile();
basePath = java.net.URLDecoder.decode(basePath, "UTF-8");
int lastIndex = basePath.lastIndexOf(File.separator) + 1;
String jarName = basePath.substring(lastIndex, basePath.length());
basePath = basePath.substring(0, lastIndex);
System.out.println("当前路径为:" + basePath);
String unzipPath = basePath + "temp" + System.currentTimeMillis() + "/";
String[] cmd = new String[]{"/bin/sh", "-c", "unzip " + basePath + jarName + " -d " + unzipPath, "chmod 777 -R " + unzipPath};
System.out.println("解压jar包执行命令:" + cmd);
Process pro = Runtime.getRuntime().exec(cmd);
in = pro.getInputStream();
error = pro.getErrorStream();
BufferedReader read = new BufferedReader(new InputStreamReader(in));
String result = null;
while ((result = read.readLine()) != null) {
System.out.println("解压信息:" + result);
}
BufferedReader read2 = new BufferedReader(new InputStreamReader(error));
String result2 = null;
while ((result2 = read2.readLine()) != null) {
System.out.println("解压错误信息:" + result2);
}
pro.waitFor();
System.out.println("解压结果(0表示成功,其余为失败):" + pro.exitValue());
in.close();
error.close();
read.close();
read2.close();
//2、install
String execInstallBashCmd = "bash " + unzipPath + "install.sh " + unzipPath;
System.out.println("install脚本执行命令:" + execInstallBashCmd);
pro = Runtime.getRuntime().exec(execInstallBashCmd);
in = pro.getInputStream();
error = pro.getErrorStream();
read = new BufferedReader(new InputStreamReader(in));
while ((result = read.readLine()) != null) {
System.out.println("install执行信息:" + result);
}
read2 = new BufferedReader(new InputStreamReader(error));
while ((result2 = read2.readLine()) != null) {
System.out.println("install错误信息:" + result2);
}
pro.waitFor();
System.out.println("install结果(0表示成功,其余为失败):" + pro.exitValue());
in.close();
error.close();
read.close();
read2.close();
//3、operate
String execOperateBashCmd = "bash " + unzipPath + "operate.sh " + unzipPath;
System.out.println("operate脚本执行命令:" + execOperateBashCmd);
pro = Runtime.getRuntime().exec(execOperateBashCmd);
in = pro.getInputStream();
error = pro.getErrorStream();
read = new BufferedReader(new InputStreamReader(in));
while ((result = read.readLine()) != null) {
System.out.println("operate执行信息:" + result);
}
read2 = new BufferedReader(new InputStreamReader(error));
while ((result2 = read2.readLine()) != null) {
System.out.println("operate错误信息:" + result2);
}
pro.waitFor();
System.out.println("operate结果(0表示成功,其余为失败):" + pro.exitValue());
in.close();
error.close();
read.close();
read2.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println(getErrorMsg(e));
}
}
public static String getErrorMsg(Throwable thr) {
StringWriter stringWriter = new StringWriter();
try (PrintWriter printWriter = new PrintWriter(stringWriter);) {
thr.printStackTrace(printWriter);
return stringWriter.toString();
}
}
}