Jar 包和 War 包的区别
秉徇【先有问题,才有方案】
1. 问题
1.1 前言
编译就是个翻译的过程,因为你写的高级语言程序猿能看懂,但是人机器看不懂啊,笨蛋计算机只能看懂带有上下文信息的 0 和 1 数据。发布程序时事先编译更是为了加快执行速度,因为直接能听懂怎么地也比同声传译要快啊。
至于为啥 Java 程序编译成 .class 文件而不直接编译成二进制文件,是为了实现 Java 的跨平台。编译成 .class 文件是为了 JVM 能看懂,不同的平台都有对应的 JVM 版本,只需平台事先安装了 JVM,就能实现一份 .class 文件,四处可执行。
1.2 打包
打个比方,现在需要搬家,看着乱糟糟的房间,怎么搬?
我会想如果能把房间原封不动地整个搬走,然后直接放在目的地最好了,这样当然最快、最方便,但是嵌在地下几十米的地桩让我望而却步。一个可替代的方法就是住在集装箱里,集装箱是独立的,想要搬家完全可以把集装箱整个搬走,然后到目的地固定好就可以了。这个集装箱大概就类似 Docker 吧。
所以我觉得完全可以不打包,把开发环境下的一整套东西都放在一个 Docker 容器里,哪儿需要搬到那儿就行了,直接和开发时一样启动运行就好了,不用编译啥的。
扯远了。现在面对的是编译好的 .class 文件和一些其它的 Web 资源文件,就像面对房间四处乱放的东西,怎么搬比较快而方便?
2. 方案
我肯定是要整理打包一下,这样才能节省运输成本。例如一个纸箱📦里,我整整齐齐由大到小合理码好物品,尽可能填满空间,这样一来我花费的纸箱个数就会大大减少,然后集中放在一个大箱子里,直接搬一个大箱子就完成了搬家任务。其实,这对应地就是文件组织和文件压缩。
Jar 和 War 文件都是使用 Java jar 工具简单压缩得到的文件。Jar 和 War 都是一种文件格式,都是基于 Zip 的文件格式,所以完全可以将文件后缀改成 .zip,然后解压查看压缩文件内容。可见,Jar 和 War 文件本质上只是一个压缩文件。Jar 和 War 文件可以看成就是上面的大箱子,而里面的各个子目录相当于小纸箱子,合理摆放物品、衣服抽真空啥的相当于压缩过程了
2.1 Jar
如下所示,是简单的 Jar 文件结构。
META-INF/
MANIFEST.MF --关于归档文件的额外的元数据信息
com/
young/
ExampleApplication.class
当然,Jar 文件的结构肯定不止于这么简单,可以是多样的。如下图 1 是 SpringBoot Build 后打的一个 jar 包结构。
![](https://img.haomeiwen.com/i8368468/10712e7179abd7d2.png)
其中 META-INF / MANIFEST.MF 文件是对一些关键文件及文件目录做了说明,如下所示,就像在大箱子上贴的一个标签,说明哪个重要的纸箱子在大箱子的什么位置。
Manifest-Version: 1.0
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: ir.springBootApplication
Spring-Boot-Version: 2.2.4.RELEASE
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
2.2 War
War 即 Web application Archive。如下所示,是简单 War 文件结构。
META-INF/
MANIFEST.MF --关于归档文件的额外的元数据信息
WEB-INF/
web.xml
jsp/
helloWorld.jsp
classes/
static/
templates/
application.properties
lib/
*.jar
其中,WEB-INF 文件目录是公开的,里面存储着所有的静态 Web 资源文件,例如 HTML、JS、CSS 文件。同时还包括其它文件,如 web.xml 文件,它是这Web 应用的配置文件,而 classes 目录下则包含编译好的 servlet 类或者 servlet 所依赖的其他类。通常这些所依赖的类也可以打包成 jar 包放在 WEB-INF 下的 lib 目录下。
2.3 Jar & War 区别
-
War 文件和 Jar 文件的区别主要就在于 War 文件有特定的结构,即得有 WEB-INF 和 META-INF 目录,除去这一点,即若 War 文件没有特定结构,War 文件其实就是一个 Jar 文件。
-
为什么 War 文件需要有特定结构?因为这个 War 结构就是被设计用来作为一个单元部署到 Web 应用服务器中的(如 Tomcat、Jetty、JBoss 等 Servlet/JSP 容器)。即 War 文件代表的不止是一个类归档文件,更是一个 Web 应用程序;而 Jar 文件则只代表是个类归档文件。
-
既然 War 文件代表一个 Web 应用程序,故 War 文件常常是包含组成 Web 应用的所有类型文件,而 Jar 则没什么限制,只是把类和相关的资源封装到压缩的归档文件中。
In software engineering, a WAR file (Web Application Resource or Web application ARchive ) is a file used to distribute a collection of JAR-files, JavaServer Pages, Java Servlets, Java classes, XML files, tag libraries, static web pages (HTML and related files) and other resources that together constitute a web application.
- 我们已经可以看出,War 文件只用于 Web 应用程序;而 Jar 文件用于library、plugin or any kind of application。
参考资料
https://stackoverflow.com/questions/5871053/difference-between-jar-and-war-in-java
https://en.wikipedia.org/wiki/WAR_(file_format)