美文网首页
利用jar命令更新jar包中文件或打包

利用jar命令更新jar包中文件或打包

作者: sdevil507 | 来源:发表于2022-05-19 21:53 被阅读0次

    背景

    有些时候会遇到一些特殊情况需要紧急对线上应用进行修复,而且没有办法本地重新打包发布时,利用jar命令进行更新或打包会是处理该问题的一种方式。
    比如:这次我们需要紧急更新线上应用中的xml文件内的一段sql语句。

    jar命令详解

    命令行输入jar可以看到该命令用法如下:

    用法: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...
    选项:
    -----------------------------------------------------------------------------------
    其中 {ctxui} 是 jar 命令的子命令,每次 jar 命令只能包含 ctxu 中的一个
    -----------------------------------------------------------------------------------
        -c  创建新的 JAR 文件包
        -t  列出 JAR 文件包的内容列表(配合grep命令筛选)
        -x  从 JAR 文件中提取指定的 (或所有) 文件
        -u  更新已存在的 JAR 文件包 (添加文件到 JAR 文件包中)
        -i  为指定的 jar 文件生成索引信息
    -----------------------------------------------------------------------------------
    [vfmn0PMe] 中的选项可以任选,也可以不选,它们是 jar 命令的选项参数
    -----------------------------------------------------------------------------------
        -v  在标准输出中生成详细输出
        -f  指定 JAR 文件名,通常这个参数是必须的
        -m  指定需要包含的 MANIFEST 清单文件
        -n  创建新档案后执行 Pack200 规范化
        -e  为捆绑到可执行 jar 文件的独立应用程序
            指定应用程序入口点
        -0  仅存储; 不使用任何 ZIP 压缩
        -P  保留文件名中的前导 '/' (绝对路径) 和 ".." (父目录) 组件
        -M  不产生所有项的清单(MANIFEST〕文件,此参数会忽略 -m 参数
    -----------------------------------------------------------------------------------
    [jar-file] 即需要生成、查看、更新或者解开的 JAR 文件包,它是 -f 参数的附属参数
    -----------------------------------------------------------------------------------
    [manifest-file] 即 MANIFEST 清单文件,它是 -m 参数的附属参数
    -----------------------------------------------------------------------------------
    [entry-point] mian函数入口,它是 -e 参数的附属参数
    -----------------------------------------------------------------------------------
    [-C dir] 表示转到指定目录下去执行这个 jar 命令的操作。它相当于先使用 cd 命令跳转至该目录下,
    再执行不带 -C 参数的 jar 命令,它只能在创建和更新 JAR 文件包的时候可用。
    -----------------------------------------------------------------------------------
    files ... 指定一个文件/目录列表(使用空格进行分隔),这些文件/目录就是要
    添加到 JAR 文件包中的文件/目录。
    如果指定了目录,那么 jar 命令打包的时候会自动把该目录中的所有文件和子目录打入包中。
    -----------------------------------------------------------------------------------
    注意:
    清单文件名, 档案文件名和入口点名称的指定顺序与 'm', 'f' 和 'e' 标记的指定顺序相同。
    
    示例 1: 将两个类文件归档到一个名为 classes.jar 的档案中:
           jar cvf classes.jar Foo.class Bar.class
    示例 2: 使用现有的清单文件 'mymanifest' 并
           将 foo/ 目录中的所有文件归档到 'classes.jar' 中:
           jar cvfm classes.jar mymanifest -C foo/ .
    

    方式一:提取/更新方式完成替换

    1. 通过命令查找文件相对路径
    jar tvf test.jar | grep 'xxx.xml'
    ------显示如下------
    6324 Thu May 19 15:55:32 CST 2022 BOOT-INF/classes/com/xxx/test/xxx.xml
    
    1. 根据路径提取文件
    jar xvf test.jar BOOT-INF/classes/com/xxx/test/xxx.xml
    

    文件会被提取到test.jar同级目录中并且路径与jar包中存在路径一致

    1. 针对得到文件进行修改或者替换
    2. 将新文件替换至jar包中
    # 注意此处的 '0' 参数,springboot应用打包未使用压缩,所以此处必须设置
    jar uvf0 test.jar BOOT-INF/classes/com/xxx/test/xxx.xml
    
    1. 以上操作,则完成了全部替换。(替换文件可以是:jar包、class文件、普通文件等全部文件)

    方式二:采用打包方式替换

    1. 将jar包通过 7z 或者 The Unarchiver 等应用解压缩成目录
    2. 在解压后的目录中找到需要替换的文件,执行替换操作
    3. cd进目录,执行打包命令重新进行打包操作
    # 注意此处的 '0' 参数,springboot应用打包未使用压缩,所以此处必须设置
    jar cvfm0 test.jar META-INF/MANIFEST.MF .
    
    1. 以上操作,则完成了全部替换。

    关于压缩后报错与参数 '0' 的问题

    由于springboot规定嵌套的jar包不能在被压缩的情况下存储,因此如果打包或者更新命令未携带参数 '0' 的情况下,会出现如下报错:

    Unable to open nested entry 'BOOT-INF/lib/xxx.jar'.
    It has been compressed and nested jar files must be stored without compression.
    

    此处需要注意。

    相关文章

      网友评论

          本文标题:利用jar命令更新jar包中文件或打包

          本文链接:https://www.haomeiwen.com/subject/kdatprtx.html