MelonBlog

java运行时查询jar包的构建信息

场景

我想看服务器上的jar包是什么时候打的包,用来排查问题,但是又不想每次都进服务器里看。

解决思路

要解决这个问题,我觉得需要再打包的时候记录一个时间,并且能够在jar包运行时能看到。

maven是有办法执行一个shell脚本的, 所以我需要写一个shell脚本讲打包信息写到jar包里,如果让maven的package命令执行之前能够触发这个shell脚本,那这个打包信息就能够打进最新的jar包,然后通过一个健康检查接口来访问这个打包信息,这样每个jar包都有自己的构建信息了,并且能够运行时查询。

代码

hook.sh

#!/bin/bash
echo "{\"date\": \"$(date)\",\"user\": \"$(whoami)\"}" > src/main/resources/build/info.txt

pom.xml

插件执行阶段要在compile之前,所以generate-sources 是一个不错的选择

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>exec</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <executable>${basedir}/src/main/resources/build/hook.sh</executable>
    </configuration>
</plugin>

info.txt

{"date": "Tue Jan  9 15:09:32 CST 2024","user": "melon"}

HealthController.java

@RequestMapping("/health")
@RestController
public class HealthController {
    @GetMapping("/now")
    public String check() {
        return FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss").format(new Date());
    }
    @GetMapping("/build_info")
    public String version() throws IOException {
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream("build/info.txt");
        if (inputStream == null) {
            return "unknown";
        }
        byte[] bytes = inputStream.readAllBytes();
        inputStream.close();
        return new String(bytes);
    }
}

curl

curl 'http://localhost:8080/health/build_info'
{"date": "Tue Jan  9 15:09:32 CST 2024","user": "melon"}