jar命令

jar的作用

  • jar(Java Archive)能够将多个源码、资源等文件打包到一个归档文件中。
  • jar是jdk自带的打包工具,它是通过zip格式进行打包的,它也可以用来进行日常的压缩、解压。

jar的使用示例

  • jar命令打包会默认在压缩包中添加清单(Manifest)文件,如果不想添加默认的manifest文件,可手动指定-M选项:

jar cvf HelloWorld.jar HelloWorld.class // 将class文件压缩成jar包
jar tf HelloWorld.jar // jar包包含文件列表
META-INF/
META-INF/MANIFEST.MF
HelloWorld.class

  • jar xf HelloWorld.jar META-INF/MANIFEST.MF // 解压出manifest文件
  • jar cvfm HelloWorld.jar MY_MANIFEST.MF HelloWorld.class // 使用自己定义的清单文件
  • jar uf HelloWorld.jar HelloWorld.txt // 向压缩包中添加文件

Manifest文件的作用

  • 上面提到在使用jar压缩文件中会默认添加 Manifest清单文件,那么这个文件是用来干啥的呢? 有何作用? 查看manifest文件的内容可以知道它记录着jar包的版本信息、创建时间,如果指定jar包的入口程序,-e选项,清单文件中就会多一行Main-Class: HelloWorld, 也可以不使用-e选项,直接创建自己的清单文件,写入Main-Class: 启动类,然后适用-m选项,使用自己的清单文件。
  • 在运行java命令的时候, 如果指定了-jar选项,那么环境变量ClASSPATH和在命令行中指定的所有类路径都会被jvm所忽略,如果jar包的class需要依赖其他的jar包,解决方案有两个,方案1:不带-jar选项, 使用java -cp 把该jar和所依赖的jar所在路径都作为classpath,后面带全限定名的启动类。方案2:使用-jar选项, java -jar hello.jar,但需要修改manifest文件中的内容,添加Class-Path来指定运行需要的其他jar,多个jar之间用空格隔开,如下所示:

Manifest-Version: 1.0
Main-Class: com.ibm.portalnews.entrance.Main
Class-Path: lib\commons-collections-3.2.jar lib\commons-configuration-1.5.jar lib\commons-lang-2.3.jar lib\commons-logging.jar lib\dom4j-1.6.1.jar lib\jaxen-1.1-beta-7.jar lib\jdom.jar lib\log4j-1.2.14.jar

Manifest-Version表示版本号, Main-Class 是jar文件的主类,程序的入口,Class-Path 指定需要的jar的路径,多个jar必须要在一行上,以空格隔开,注意:对于文件路径,windows下使用\来分割,linux下用/分割。 在清单文件中, 所有选项的冒号后面必须加个空格,最后一行必须是一个回车换行符。

jar cvfM AppServer.jar META-INF/MANIFEST.MF AppServer.class
jar uf AppServer.jar AppServer$1.class // \ 用于mac上转义
java -jar AppServer.jar server1 // 直接执行jar, server1 是参数
unzip AppServer.jar -d mytest // unzip 解压

是否可以将jar包A引用的其他jar包一同打包到A里面? 这样的话就很方便统一管理了,遗憾的是这样是不行的,java 类加载器是无法加载jar包内包含的其他jar包的class,这里可以使用-0 选项,它表示只打包不压缩, jar -cvf0m , 这样打的包不会压缩,classloader就可以加载其他jar中包含的class文件了。(貌似maven shade-plugin就是这么做的??)

jar cvf0M smconfweb.jar META-INF/MANIFEST.MF *

MANIFEST 作用

从 MANIFEST 文件中提供的信息大概可以了解到其基本作用

  • JAR 包基本信息描述
  • Main-Class 指定程序的入口,这样可以直接用java -jar xxx.jar来运行程序
  • Class-Path 指定jar包的依赖关系,class loader会依据这个路径来搜索class

Jar 文件和 Manifest 在 java 中的定义

下面为 JarFile 的定义,从代码就可以看出,前面我们所介绍的 Jar 是以 ZIP 格式构建一种归档文件,因为它是 ZipFile 的子类。

public class JarFile extends ZipFile {
    private SoftReference<Manifest> manRef;
    private JarEntry manEntry;
    private JarVerifier jv;
    private boolean jvInitialized;
    private boolean verify;
    //指示是否存在Class-Path属性(仅当hasCheckedSpecialAttributes为true时才有效)
    private boolean hasClassPathAttribute;
    // 如果清单检查特殊属性,则为 true
    private volatile boolean hasCheckedSpecialAttributes;
    // 在SharedSecrets中设置JavaUtilJarAccess
    static {
        SharedSecrets.setJavaUtilJarAccess(new JavaUtilJarAccessImpl());
    }
    /**
     * The JAR manifest file name.(JAR清单文件名)
     */
    public static final String MANIFEST_NAME = "META-INF/MANIFEST.MF";
    // 省略其他
}

下面是 Manifest 类的定义,用来描述 JAR 的 清单文件。从其属性中也很好的观察到,其存储的就是 K-V 键值对数据

public class Manifest implements Cloneable {
    // manifest main attributes
    private Attributes attr = new Attributes();
    // manifest entries
    private Map<String, Attributes> entries = new HashMap<>();
    // 省略其他
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本文详细讲述了JAR命令的用法,对于大家学习和总结jar命令的使用有一定的帮助作用。具体如下: JAR包是Java...
    Santiagogogo阅读 8,263评论 0 2
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,323评论 19 139
  • 1、jar简介 Java归档文件格式(Java Archive, JAR)能够将多个源码、资源等文件打包到一个归档...
    SpaceCat阅读 40,249评论 4 64
  • 打好jar包之后还需要更改清单文件的. 打开生成的jar,里面有一个MANIFEST.MF的文件把它打开. 然后有...
    AnnieAri阅读 4,408评论 0 0
  • 1.编写manifest文件如此目录下的manifest文件,注意格式,key-value之间要有空格最后一行必须...
    和谐共处阅读 4,500评论 0 1