java 获取MANIFEST.MF信息(外置Tomcat部署项目之微服务增加公共启动方式实战)

文章讲述了如何在Java中通过ClassLoader获取jar/war包的启动目录,读取MANIFEST.MF文件以获取启动类的全限定名,然后使用反射加载启动类,以完成SpringBoot应用的自定义配置和初始化。这个过程适用于理解和处理基于Java的web应用启动逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、在common包下创建servlet包,添加ServletInitializer启动类

2、代码

参考代码1

JarFile jarFile = 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);
    }
    //log.debug("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) {
        StringWriter writer = new StringWriter();
        FileCopyUtils.copy(new InputStreamReader(jarFile.getInputStream(entry)), writer);
        jarFile.close();
        String content = IOUtils.toString(new StringReader(writer.toString()));
        //log.debug("MANIFEST.MF content:" + content);
        return content;
    } else {
        return null;
    }
} catch (Exception ex) {
    //log.error("error when reading MANIFEST.MF", ex);
} finally {
    if (jarFile != null) {
        //jarFile.close();
    }
}

参考代码2

解决方案:

/*
 * 解决思路
 * 1、通过ClassLoader获取jar/war包启动目录
 * 2、通过FileReader流,获取当前启动jar/war包中的源信息
 * 3、通过Properties对象,以key\value的方式拿到当前启动类的全路径类名
 * 4、通过反射拿到指定启动类
 * 5、完成
 * */

代码:

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)   {
    isEmbedded = false;
    Class lanhaiServiceApplication = null ;
    Properties properties = new Properties();
    try{
        //获取当前启动的jar/war目录
        String path = ClassUtils.getDefaultClassLoader().getResource("").getPath();
        log.info("war/jar包启动完整路径:"+path);
        //获取的war包的路径为/WEB-INF/classes/,jar包路径为/BOOT-INF/classes,故需要做war包专属替换
        String jarFilePath = ClassUtils.getDefaultClassLoader().getResource("").getPath().replace("/WEB-INF/classes/", "");
        /*if (jarFilePath.startsWith("file")) {
            jarFilePath = jarFilePath.substring(5);
        }*/
        log.info("tomcat中当前war/jar包根目录:"+jarFilePath);
        //获取当前启动war包的源信息
        FileReader fileReader
                = new FileReader(jarFilePath+"/META-INF/MANIFEST.MF");
        log.info("当前启动war包的源信息目录:"+jarFilePath+"/META-INF/MANIFEST.MF");
        if (fileReader!=null){
            properties.load(fileReader);
            fileReader.close();
            String classname = properties.getProperty("Start-Class");
            log.info("当前启动war包的全限定类名为:"+classname);
            if (classname!=null){
                //反射当前启动类
                lanhaiServiceApplication = Class.forName(classname);
            }
        }
    }catch (Exception e){
    e.printStackTrace();
    }
    log.info("服务开始启动");
    return application.sources(lanhaiServiceApplication);
}

其中:

/*
*其中获取的war包启动目录未覆盖之前路径为:
*home/chrtc/jar/apache-tomcat-9.0.67/webapps/lanhai-system-app/WEB-INF/classes/
*由于源信息在MATE-INF目录下,所以需要将后面的两段路径覆盖并拼接上我们实际要获取到的文件路径:
*home/chrtc/jar/apache-tomcat-9.0.67/webapps/lanhai-system-app/META-INF/MANIFEST.MF
* */

参考链接1:java怎么读取MANIFEST.MF文件获取其中属性-百度经验

参考链接2:https://www.cnblogs.com/wanbao/p/9662621.html

参考链接3(源码分析):java原生和SpringBoot读取jar包中MANIFEST.MF的方式_springboot manifest.mf_brucelwl的博客-优快云博客

jar/war包启动原理:https://blog.youkuaiyun.com/z69183787/article/de

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值