JAR文件

在将应用程序打包时,你一定希望只向用户提供一个单独的文件,而不是一个包含大量类文件的目录结构,Java归档(JAR)文件就是为此目的而设计的。一个JAR文件既可以包含类文件,也可以包含诸如图像和声音等其他类型的文件。此外,JAR文件是压缩的,它使用了我们熟悉的ZIP压缩格式。

创建JAR文件

可以使用jar工具制作JAR文件(在默认的JDK安装中,这个工具位于jdk/bin目录下)。创建一个新JAR文件最常用的命令使用以下语法:

jar cvf jarFileName file1 file2 . . .

例如:

jar cvf Calculatorclasses.jar *.class icon.gif

通常,jar命令的格式如下:

jar options file1 file2 . . .

jar程序选项

表(jar程序选项)列出了jar程序的所有选项。它们类似于UNIX tar命令的选项。

可以将应用程序和代码库打包在JAR文件中。例如,如果想在一个Java程序中发送邮件,就可以使用打包在文件javax.mail.jar中的一个库。

选项 说明
c 创建一个新的或者空的存档文件并加入文件。如果指定的文件名是目录,jar程序将会对它们进行递归处理
C 临时改变目录,例如:jar cvf jarFileName.jar -C classes *.class切换到classes子目录以便增加类文件
e 在清单文件中创建一个入口点
f 指定JAR文件名作为第二个命令行参数。如果没有这个参数,jar命令会将结果写至标准输出(在创建JAR文件时)或者从标准输入读取(在解压或者列出JAR文件内容时)
i 建立索引文件(用于加快大型归档中的查找)
m 将一个清单文件添加到JAR文件中。清单是对归档内容和来源的一个说明。每个归档有一个默认的清单文件。但是,如果想验证归档文件的内容,可以提供自己的清单文件
M 不为条目创建清单文件
t 显示内容表
u 更新一个已有的JAR文件
V 生成详细的输出结果
X 解压文件。如果提供一个或多个文件名,只解压这些文件;否则,解压所有文件
0 存储,但不进行ZIP压缩

清单文件

除了类文件、图像和其他资源外,每个JAR文件还包含一个清单文件(manifest),用于描述归档文件的特殊特性。

清单文件被命名为MANIFEST.MF,它位于JAR文件的一个特殊的META-INF子目录中。符合 标准的最小清单文件极其简单:

Manifest-Version: 1.0

复杂的清单文件可能包含更多条目。这些清单条目被分成多个节。第一节被称为主节(main section)。它作用于整个JAR文件。随后的条目用来指定命名实体的属性,如单个文件、包或者URL。它们都必须以一个Name条目开始。节与节之间用空行分开。例如:

Manifest-Version: 1.0
lines describing this archive Name: Woozle.class
lines describing this file
Name: com/mycompany/mypkg/
lines describing this package

要想编辑清单文件,需要将希望添加到清单文件中的行放到文本文件中,然后运行:

jar cfm jarFileName manifestFileName . . .

例如,要创建一个包含清单文件的JAR文件,应该运行:

jar cfm MyArchive.jar manifest.mf com/mycompany/mypkg/*.class

要想更新一个已有的JAR文件的清单,则需要将增加的部分放置到一个文本文件中,然后执行以下命令:

jar ufm MyArchive.jar manifest-additions.mf

注释

请参看https://docs.oracle.com/javase/10/docs/specs/jar/jar.html获得有关JAR文件和清单文件格式的更多信息。

可执行JAR文件

可以使用jar命令中的e选项指定程序的入口点,即通常需要在调用java程序启动器时指定的类:

jar cvfe MyProgram.jar com.mycompany.mypkg.MainAppClass files to add

或者,可以在清单文件中指定程序的主类,包括以下形式的语句:

Main-Class: com.mycompany.mypkg.MainAppClass

不要为主类名增加扩展名.class

警告

清单文件的最后一行必须以换行符结束。否则,清单文件将无法被正确地读取。 常见的一个错误是创建了一个只包含Main-Class行而没有行结束符的文本文件。

不论使用哪一种方法,用户可以简单地通过下面的命令来启动程序:

java -jar MyProgram.jar

取决于操作系统的配置,用户甚至可以通过双击JAR文件图标来启动应用程序。下面是各种操作系统的操作方式:

  • 在Windows平台中,Java运行时安装程序将为”.jar”扩展名创建一个文件关联,会用javaw -jar命令启动文件(与java命令不同,javaw命令不打开shell窗口)。
  • 在Mac OS X平台中,操作系统能够识别".jar"扩展名文件。双击JAR文件时就会执 行Java程序。

不过,人们对JAR文件中的Java程序与原生应用还是感觉不同。在Windows平台 中,可以使用第三方的包装器工具将JAR文件转换成Windows可执行文件。包装器是一个Windows程序,有大家熟悉的扩展.exe,它可以查找和加载Java虚拟机(JVM),或者在没有找到JVM时会告诉用户应该做些什么。有许多商业的和开源的产品,例如,Launch4J (http://launch4j.soureforge.net)和 IzPack

http://izpack.org)。

多版本JAR文件

随着模块和包强封装的引入,之前可以访问的一些内部API不再可用。例如,JavaFX 8有一个内部类com.sun.javafx.css.CssParser。如果用它解析一个样式表,你会发现你的程序不再能正常编译了。补救很简单,只需要改用Java 9提供的javafx.css.CssParser。不过这样会有一个问题。你需要向Java 8和Java 9用户发布不同的应用程序,或者需要利用类加载和反射等一些技巧。

为了解决类似这样的问题,Java 9引入了多版本JAR(multi-release JAR),其中可以包含面向不同Java版本的类文件。

为了保证向后兼容,额外的类文件放在META-INF/versions目录中:

Application.class
BuildingBlocks.class
Util.class
META-INF
|__ MANIFEST.MF (with line Multi-Release: true)
|__ versions
|__ 9
| |__ Application.class
| |__ BuildingBlocks.class
|__ 10
|__ BuildingBlocks.class

假设Application类使用了CssParser类。那么遗留版本的Application.class文件可以使用com.sun.javafx.css.CssParser,而Java 9

版本可以使用javafx.css.CssParser

Java 8完全不知道META-INF/versions目录,它只会加载遗留的类。Java 9读取这个JAR文件时,则会使用新版本。

要增加不同版本的类文件,可以使用--release标志:

jar uf MyProgram.jar --release 9 Application.class

要从头构建一个多版本JAR文件,可以使用-C选项,对应每个版本要切换到一个不同的类文件目录:

jar cf MyProgram.jar -C bin/8 . --release 9 -C bin/9 Application.class

面向不同版本编译时,要使用--release标志和-d标志来指定输出目录:

javac -d bin/8 --release 8 . . .

在Java 9中,-d选项会创建这个目录(如果原先该目录不存在)。

--release标志也是Java 9新增的。在较早的版本中,需要使用-source-target-boot-classpath标志。JDK现在为之前的两个API版本提供了符号文件。在Java 9中,编译时可以将--release设置为9、8或7。

多版本JAR并不适用于不同版本的程序或库。对于不同的版本,所有类的公共API都应当是一样的。多版本JAR的唯一目的是支持你的某个特定版本的程序或库能够在多个不同的JDK版本上运行。如果你增加了功能或者改变了一个API,那就应当提供一个新版本的JAR。

注释

javap之类的工具并没有改造为可以处理多版本JAR文件。如果调用:

javap -classpath MyProgram.jar Application.class

你会得到类的基本版本(毕竟,它与更新的版本应该有相同的公共API)。如果必须查看更新的版本,可以调用:

javap -classpath MyProgram.jar\!/META-INF/versions/9/Application.class

关于命令行选项的说明

Java开发包(JDK)的命令行选项一直以来都使用单个短横线加多字母选项名的形式,如:

java -jar . . .
javac -Xlint:unchecked -classpath . . .

jar命令是个例外,这个命令遵循经典的tar命令选项格式,而没有短横线:

jar cvf . . .

从Java 9开始,Java工具开始转向一种更常用的选项格式,多字母选项名前面加两个短横线,另外对于常用的选项可以使用单字母快捷方式。例如,调用Linux Is命令时可以提供 一个 “ human-readable ” 选项:

ls命令时可以提供一个“human-readable”选项:

ls --human-readable

或者

ls -h

在Java 9中,可以使用--version而不是-version,另外可以使用--class-path而不是-classpath

详细内容可以参见JEP 293增强请求(http://openjdk.java.net/jeps/293)。在所有清理工作中,作者还提出要标准化选项参数。带--和多字母的选项的参数用空格或者一个等号(=)分隔:

javac --class-path /home/user/classdir . . .

javac --class-path=/home/user/classdir . . .

单字母选项的参数可以用空格分隔,或者直接跟在选项后面:

javac -p moduledir . . .

javac -pmoduledir . . .

警告

后一种方式现在不能使用,而且一般来讲这也不是一个好主意。如果模块目录 恰好是arametersrocessor,这就很容易与遗留的选项发生冲突,这又何必呢?

无参数的单字母选项可以组合在一起:

jar -cvf MyProgram.jar -e mypackage.MyProgram */*.class

警告

目前不能使用这种方式。这肯定会带来混淆。假设javac有一个-c选项。那么javac -cp是指javac -c-p还是-cp

这就会带来一些混乱,希望过段时间能够解决这个问题。尽管我们想要远离这些古老的jar选项,但最好还是等到尘埃落定为妙。不过,如果你想做到最现代化,那么可以安全地使用jar命令的长选项:

jar --create --verbose --file jarFileName file1 file2 . . .

对于单字母选项,如果不组合,也是可以使用的:

jar -c -v -f jarFileName file1 file2 . . .

JAR文件的更多相关文章

  1. hibernate5.2需要的最少jar文件

    hibernate5.2需要的最少jar文件: required文件夹中的所有jar文件 + mysql-connector-java-bin.jar.

  2. Struts2.5需要的最少jar文件

    以Struts2.5.2为例 从官网上下载“struts-2.5.2-min-lib.zip”,里面有7个jar文件: commons-fileupload-1.3.2.jarcommons-io-2 ...

  3. 使用Mavne生成可以执行的jar文件

    到目前为之,还没有运行HelloWorld的项目,不要忘了HelloWorld类可是有一个main方法的.使用mvn clean install命令默认生成的jar 包是不能直接运行的.因为带有mai ...

  4. 编译protobuf的jar文件

    1.准备工作 需要到github上下载相应的文件,地址https://github.com/google/protobuf/releases protobuf有很多不同语言的版本,因为我们需要的是ja ...

  5. Android项目实战(二十四):项目包成jar文件,并且将工程中引用的jar一起打入新的jar文件中

    前言: 关于.jar文件: 平时我们Android项目开发中经常会用到第三方的.jar文件. 其实.jar文件就是一个类似.zip文件的压缩包,里面包含了一些源代码,注意的是.jar不包含资源文件(r ...

  6. linux下shell脚本执行jar文件

    最近在搞一个shell脚本启动jar文件个关闭jar文件的东东.搞得我都蛋疼了.今天晚上终于弄好了 话说,小弟的linux只是刚入门,经过各方查资料终于搞定了.话不多说,下面开始上小弟写的shell脚 ...

  7. maven 生成可执行的jar文件

    微服务的热潮,慢慢讲jar引入了码农的视线之中,从传统web开发中过来的人面对这个东西也算是个新鲜事了,接下来聊一聊在maven下生成可运行jar的那些事. Maven可以使用mvn package指 ...

  8. [转]MyEclipse 里查看jar文件源码

    在开发过程中,有时候需要查看jar文件的源码,这里讲解如何设置.  选中某一个jar文件,如我这里选中的是struts2-core-2.1.6.jar,然后右键-->Properties--&g ...

  9. 向Maven的本地库中添加jar文件

    有时我们要用的 maven 依赖项在官方repo库中找不到,然而我们从其他渠道获得了依赖项中的所有jar文件,本文记录了如何向本地库添加jar文件. 从复杂到简单,有三种方法: 使用 maven 的仓 ...

  10. myeclipse(2015)中创建简单的Maven项目的步骤(用于生成可执行jar文件)------》myeclipse2015

    利用MyEclipse的引导,可以很方便的创建简单的.用于生成可执行jar文件的Maven项目: 1.New -> Project... 选择 Maven Project, 点击Next > ...

随机推荐

  1. 剖析虚幻渲染体系(11)- RDG

    目录 11.1 本篇概述 11.2 RDG基础 11.2.1 RDG基础类型 11.2.2 RDG资源 11.2.3 RDG Pass 11.2.4 FRDGBuilder 11.3 RDG机制 11 ...

  2. Java并发之AQS原理解读(三)

    上一篇:Java并发之AQS原理解读(二) 前言 本文从源码角度分析AQS共享锁工作原理,并介绍下使用共享锁的子类如何工作的. 共享锁工作原理 共享锁与独占锁的不同之处在于,获取锁和释放锁成功后,都会 ...

  3. 百闻不如一试——公式图片转Latex代码

    写博客时,数学公式的编辑比较占用时间,在上一篇中详细介绍了如何在Markdown中编辑数学符号与公式. https://www.cnblogs.com/bytesfly/p/markdown-form ...

  4. Android kotlin http url request

    kotlin.concurrent.thread{ val url = "https://hangj.cnblogs.com/" val res = try { java.net. ...

  5. vue js 手写 正则判断 手机号码 和 密码

    const phoneOrEmails = /^1[3|4|5|6|7|8|9][0-9]\d{8}$/             if(this.ruleForms.phoneOrEmail  ==  ...

  6. Django——后台管理

    1.要使用Django-admin后台的前提 INSTALLED_APPS = [ 'simpleui', 'django.contrib.admin', #必须有这一项 'django.contri ...

  7. 性能测试必备命令(2)- uptime

    性能测试必备的 Linux 命令系列,可以看下面链接的文章哦 https://www.cnblogs.com/poloyy/category/1819490.html 介绍 系统启动up了(运行了)多 ...

  8. 7-31 堆栈操作合法性 (20 分) PTA

    7-31 堆栈操作合法性 (20 分)   假设以S和X分别表示入栈和出栈操作.如果根据一个仅由S和X构成的序列,对一个空堆栈进行操作,相应操作均可行(如没有出现删除时栈空)且最后状态也是栈空,则称该 ...

  9. 痞子衡嵌入式:在MDK开发环境下将关键函数重定向到RAM中执行的几种方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在MDK开发环境下将关键函数重定向到RAM中执行的几种方法. 这个关键函数重定向到 RAM 中执行系列文章,痞子衡已经写过 <IA ...

  10. (三、四)Superset 1.3图表篇——透视表-Pivot Table

    本系列文章基于Superset 1.3.0版本.1.3.0版本目前支持分布,趋势,地理等等类型共59张图表.本次1.3版本的更新图表有了一些新的变化,而之前也一直没有做过非常细致的图表教程. 而且目前 ...