java 溯本求源之基础(七)之 jar(上篇)

2024-03-26 15:28
文章标签 java 基础 jar 溯本求源

本文主要是介绍java 溯本求源之基础(七)之 jar(上篇),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        这个命令一些相关的知识点很重要!很重要!很重要!重要的事情说三遍,再说这个工具之前我们先把相关东西一口气说完

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

这篇关于java 溯本求源之基础(七)之 jar(上篇)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/848956

相关文章

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2

Spring Cloud LoadBalancer 负载均衡详解

《SpringCloudLoadBalancer负载均衡详解》本文介绍了如何在SpringCloud中使用SpringCloudLoadBalancer实现客户端负载均衡,并详细讲解了轮询策略和... 目录1. 在 idea 上运行多个服务2. 问题引入3. 负载均衡4. Spring Cloud Load

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应