问题:当jar应用部署在服务器上后,因为是用docker容器来运行, 有一烦恼不知道代码是不是最新,该容器启动的是不是从最新的镜像启动的。

        网上很多解决办法是 jar的命名加时间戳,但这会有几个问题,1、就是打包镜像时,每次都要修改这个jar包名,比较麻烦;2、在测试环镜、生产环境运行起来后也是不知道是否是最新的包。

解决办法:

     maven 打包时加入时间戳写入MANIFEST.MF,在 controller 读取MANIFEST.MF,查看时间戳 即可判断是否最新的

效果:

步骤:

1、pom.xml配置 时间戳

<modelVersion>4.0.0</modelVersion>
<artifactId>zzf-system</artifactId>
<description>系统管理app接口</description>
 <packaging>jar</packaging>
<version>${maven.build.timestamp}</version>
<properties>
<maven.build.number>1.0.5</maven.build.number>
<maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format>
</properties>

2、打包配置 

 <build>
        <finalName>${project.name}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            </plugin>
        </plugins>
    </build>

3、Controller类


/**
 *
 * @author zzf
 * 欢迎入Q群45155962一起交流
 * @version 1.00.00
 */
@Controller
@RequestMapping("/")
public class IndexController {

    /***
     * 读取 META-INF/MANIFEST.MF
     * 主要查看jar构建时间,判断该当前运行jar是否最新
     * @return
     */
    @RequestMapping("/jarinfo")
    @ResponseBody
    public  String jarinfo() {
       return JarFileUtils.readJarFile();
    }

}

4、读取MANIFEST.MF


import org.springframework.util.ClassUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 *
 * @author zzf
 * 欢迎入Q群45155962一起交流
 * @version 1.00.00
 */
public class JarFileUtils {


    public static String readJarFile() {
        JarFile jarFile = null;
        BufferedReader br = null;
        try {
            // 获取jar的运行路径,因linux下jar的路径为”file:/app/.../test.jar!/BOOT-INF/class!/“这种格式,所以需要去掉”file:“和”!/BOOT-INF/class!/“
            String jarFilePath = ClassUtils.getDefaultClassLoader().getResource("").getPath().replace("!/BOOT-INF/classes!/", "");
            if (jarFilePath.startsWith("file")) {
                jarFilePath = jarFilePath.substring(5);
            }
            System.out.println("jarFilePath:" + jarFilePath);
            // 通过JarFile的getJarEntry方法读取META-INF/MANIFEST.MF
            jarFile = new JarFile(jarFilePath);
            JarEntry entry = jarFile.getJarEntry("META-INF/MANIFEST.MF");
            // 如果读取到MANIFEST.MF文件内容,则转换为string
            if (entry != null) {
                InputStream in =  jarFile.getInputStream(entry);

                StringBuilder sb = new StringBuilder();
                br = new BufferedReader(new InputStreamReader(in));
                String line = "";
                while ((line = br.readLine()) != null) {
                    sb.append(line+"<br>");
                }
               return sb.toString();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                if(null != br){
                  br.close();
                }
                if(null != jarFile){
                    jarFile.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return  "未找到MANIFEST.MF文件";

    }

}

如果有你有更好的方式,也请留言告诉我,非常感谢

最后附上我的部署流程图:

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐