这个命令一些相关的知识点很重要!很重要!很重要!重要的事情说三遍,再说这个工具之前我们先把相关东西一口气说完
1.类是如何加载的
1.1类加载的顺序:
Bootstrap classes:
这个我们更可以理解为引导类,就像计算机一样我们电脑开机,他启动有一个bios去找引导扇区(这里只是类比,很多过程肯定不一样的),去启动,这个也是一样的,那么在java中bootstarp都在那里呢,其实就是jre下面的lib目录
Extension classes(Installed extensions):
其实这个我们之前在介绍 javac -Djava.ext.dirs=*directories*时就简单说过了,今天再次提及一下,由作者抛砖引玉,并且使用一下官网的图片。首先任何一组包或类都可以很容易地扮演扩展的角色。将一组类转换为扩展的第一步是将它们捆绑在一个JAR文件中,完成后,您可以通过两种方式将软件转换为扩展:
a.通过将JAR文件放置在Java运行时环境的目录结构中的特殊位置(其实就是/ext下),在这种情况下,它被称为已安装的扩展。那么这个是什么,目录是什么,官网中的目录结构是这样的:
额外需要注意的是从Java 6开始,扩展JAR文件也可以放置在独立于任何特定JRE的位置,这样系统上安装的所有JRE都可以共享扩展。在Java 6之前,Java .ext.dirs的值引用单个目录,但在Java 6中,它是一个目录列表(如CLASSPATH),指定搜索扩展的位置。路径的第一个元素始终是JRE的lib/ext目录。第二个元素是JRE外部的目录。另一个位置允许一次安装扩展JAR文件,并由该系统上安装的几个JRE使用。
b.通过以指定的方式从另一个JAR文件的清单中引用JAR文件,在这种情况下,它被称为下载扩展。该方式就是我们在使用 javac -Djava.ext.dirs的方式。
Class Path(类路径 include user classes) :
用户类是由开发人员和第三方定义的类,它们不利用扩展机制。我们可以使用命令行上的-classpath选项(首选)或CLASSPATH环境变量来标识这些类的位置。
2.jar命令使用
2.1 jar命令简述
jar命令是一个通用的归档和压缩工具,基于ZIP和ZLIB压缩格式。但是,jar命令主要用于将Java小程序或应用程序打包到单个归档文件中。当小程序或应用程序的组件(文件、图像和声音)组合成单个归档文件时,它们可以在单个HTTP事务中由Java代理(例如浏览器)下载,而不需要为每个组件建立新的连接。这极大地提高了下载时间。jar命令还可以压缩文件,这进一步缩短了下载时间。jar命令还允许小程序作者对文件中的单个条目进行签名,以便对它们的来源进行身份验证。无论是否压缩,JAR文件都可以用作类路径入口。
jar命令的语法类似于tar命令的语法。它有几个操作模式,由一个强制操作参数定义。其他参数要么是修改操作行为的选项,要么是执行操作所需的操作数。
2.2参数介绍
当我们在使用jar命令的时候,可以使用一些参数。以下是一部分的介绍
2.2.1必须指定的参数
c,i,t,u,x 这个是我们在使用这个命令的时候必须指定的参数,也就是2.1中提到的一些指定命令,我们简单介绍一些这些的使用
c
创建一个新的JAR归档文件。
i
为JAR存档生成索引信息。
t
列出JAR归档文件的内容。
u
更新JAR存档。
x
从JAR存档中提取文件。
2.2.2 自定义选项
2.3.2.1 -e参数
简单来说是用来覆盖原有 manifest文件中的 `Main-Class 属性的,注意是覆盖,而不是增加,那么就会有人问这个参数这个文件都是什么玩意儿,听我娓娓道来,manifest在我们打包过程中是非常常见的,只不过我们不一定会注意到,比如常见的我们一个springboot项目,在使用mvn clean package的时候,他就会出现一个jar包,当我们使用压缩工具打开时会有一个META-INF的文件夹,这个文件夹下面就有一个MANIFEST.MF的文件,就是我们说的这个东西,这个东西里面有很多值,一会儿会简单介绍下,但是我们先说这个值。
以springboot项目打包为例,笔者简单看了一下代码,在打包过程中,使用的是spring-boot-maven-plugin插件,这个插件中主要使用的则是spring-boot-loader-tools模块,在代码中使用的则是org.springframework.boot.loader.JarLauncher作为的Main-Class的值。一下是两个截图,有兴趣的朋友可以去看一下,我这里不过多赘述了,这个就是jarLauncher的实现
那么这个参数如何使用:
jar cfe output.jar MainClass input-files
MainClass
是包含main
方法的类的名称,它将作为 JAR 文件的入口点。这个类名应该使用完全限定名(包括包名)。input-files
是要包含在 JAR 文件中的文件和目录的列表。这通常包括编译后的.class
文件和其他资源文件。
为什么这个MainClass笔者会说这么多,我碰到的场景大概有两种,在我们使用java -jar 启动的时候会有找不到启动类的情况,那么很有可能就是这个不对了,1是我们可能在pom(以maven为例)设置了一些条件,可能打出来了不同的jar,此时我们要注意区分,2是有的时候去做物理机这种的更新,我们每次可能不需要全量部署,或者某些客户会有要求,上传的包不够,那么就可以修改我们的加载器,轻量化部署
扩展:
MANIFEST.MF 文件是 Java 打包工具(如 jar、war、ear 等)中必须存在的一个文件,用于描述打包文件的元信息。它的主要作用有以下两个方面:
1.指定打包文件中的主类
MANIFEST.MF 文件中的 Main-Class 属性可以指定打包文件中的主类,这个主类将会在运行时被启动。当我们使用 java -jar 命令运行一个 JAR 文件时,Java 运行时会读取 MANIFEST.MF 文件,找到 Main-Class 属性指定的类,并执行该类的 main() 方法。
2.存储打包文件的元信息
MANIFEST.MF 文件中还可以包含其他自定义属性,用于存储打包文件的元信息。例如,可以指定打包文件的版本号、作者、描述信息等。这些属性可以在运行时被读取,以提供更多的应用程序信息。
3.MANIFEST.MF有哪些配置项
1.Manifest-Version
指定 MANIFEST.MF 文件的版本号。例如 Manifest-Version: 1.0
2.Main-Class 指定打包文件的主类。
例如 Main-Class: com.example.MyMainClass
3.Class-Path 指定该 JAR 文件的类路径,以便在运行时加载其他类。
例如: Class-Path: lib/other.jar lib/some.jar
4.Created-By 指定生成该 JAR 文件的工具和版本号。
例如: Created-By: Apache Maven 3.6.3
5.Implementation-Title 指定该 JAR 文件的实现标题。
例如: Implementation-Title: My Application
6.Implementation-Version 指定该 JAR 文件的实现版本。
例如 Implementation-Version: 1.0.0-SNAPSHOT
7.Implementation-Vendor 指定该 JAR 文件的实现厂商。
例如: Implementation-Vendor: Acme Corporation
8.Implementation-Vendor-Id 指定该 JAR 文件的实现厂商 ID。
例如: Implementation-Vendor-Id: com.acme
9.Specification-Title 指定该 JAR 文件的规范标题。
例如: Specification-Title: My Application API
10.Specification-Version 指定该 JAR 文件的规范版本。
例如 Specification-Version: 1.0.0
11.Specification-Vendor 指定该 JAR 文件的规范厂商。
例如 Specification-Vendor: Acme Corporation
12.Sealed 指定该 JAR 文件是否被封闭,即是否允许其他 JAR 文件修改该 JAR 文件中的类文件。
例如: Sealed: true
在 Java 中,MANIFEST.MF 文件通常被 Java 虚拟机(JVM)或相关的工具读取和解析。
例如,当我们在命令行使用 "java -jar" 命令运行一个打包成 JAR 文件的 Java 应用程序时,JVM 会读取 JAR 文件中的 MANIFEST.MF 文件来确定应用程序的主类,从而启动应用程序。 此外,也有许多其他的工具和库可以读取和解析 MANIFEST.MF 文件,
例如 Maven 和 Gradle 等构建工具,以及一些用于操作 JAR 文件的 Java 库,如 Java Archive (JAR) API 等。这些工具和库通常会使用 Java 类库中的 java.util.jar.Manifest 类来解析 MANIFEST.MF 文件,并将其转换为 Java 对象,以便于后续的操作和使用
更多可以参照官网https://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html