java - 检查正在运行的 JAR Linux 服务的版本

标签 java linux service jar version

我有一个运行 JAR 的 initctl 服务,我需要确保它在代码更新后重新启动。

我知道我可以只写入一个带有版本的文本文件并检查它,但我想知道是否有一种方法可以构建一个带有版本标签的 JAR,以便在使用 initctl status ServiceNameHere 时查看?

任何更好的替代品也会有所帮助!

最佳答案

正确构建的 .jar 将其版本存储在其 list 或模块描述符中。 .jar 文件实际上只是一个 zip 文件,包含一个或多个特定于 Java 的特殊条目,其中最重要的是 META-INF/MANIFEST.MF,这是一个称为 list 的纯文本文件包含有关 .jar 文件内容的信息。

有几个standard attributes可能存在(尽管允许自定义属性并且实际上很常见)。标准版本之一是 Implementation-Version

因此,要确定 .jar 文件的版本,您可以使用:

unzip -p /path/to/jar META-INF/MANIFEST.MF | sed -n -e 's/^Implementation-[Vv]ersion: //p'

如果您的 .jar 文件是 Java 9+ 模块, list 属性将被忽略,因此以上内容将不起作用。在这种情况下,您需要提取模块描述符:

jar -d -f /path/to/jar | sed -n -e 's/^[^@]*@\([^ ][^ ]*\).*/\1/p'

要检查您要运行的 .jar 是否与上次运行的 .jar 具有相同的版本,请将其存储在 /var 下的某处。例如:

versionfile=/var/local/last_jar_version

version=`unzip -p /path/to/jar META-INF/MANIFEST.MF | sed -n -e 's/^Implementation-[Vv]ersion: //p'`
# For modules: version=`jar -d -f /path/to/jar | sed -n -e 's/^[^@]*@\([^ ][^ ]*\).*/\1/p'`

if [ -f "$versionfile" && "$version" = `cat "$versionfile"` ]
then
    echo Running same version of jar as last time.
else
    echo Running a different jar version: "$version"
fi

printf %s "$version" > "$versionfile"

极端情况:自 a line in a manifest may not be longer than 72 bytes (not characters) ,对于长度超过 48 个 ASCII 字符的非模块 jar 版本,这将失败。 (Implementation-Version: 是 24 个字节,72 − 24 = 48。)我从未见过这么长的版本,但我怀疑它们在那里。

关于java - 检查正在运行的 JAR Linux 服务的版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52007769/

相关文章:

c# - 启动 Windows 服务时出现错误 1053(在 Visual Studio 中创建的 exe)

java - 区分表中的行

java - Spring MVC 表单验证日期字段

linux - 更改 dicom 图像的窗口宽度和窗口级别

linux - 更改 gnome 中的美国国际撇号布局

c# - 在 IIS 上运行 Windows 服务

JavaFX:在 FXML 中从 ResourceBundle 访问非字符串对象

java - 重新抛出异常的ExecutorService

linux - #./和# 之间的区别。 ./

android - 当我禁用数据连接或 wifi 时服务停止