一文读懂Java中jar包的小秘密

.jar中没有主清单属性【已解决】 对jar解压缩,可以看到有一个MANIFEST.MF文件,此文件就是jar运行时要查找的清单目录。主清单数据,就是我们要运行的主类即程序入口,缺少主清单属性,就不知道从哪开始运行。因此我们需要对项目进行配置,指定程序入口。在pom.xml文件中进行主类配置。情况2:是SpringBoot项目。情况1:是maven项目。 阅读详情

简介

java程序员每天不是在创建jar包就是在创建jar包的路上,并且各种依赖引用都是以jar包的形式展示的。但是随着现代IDE的出现,我想很多程序员已经基本上很少直接和jar包打交道了。

换句话说,他们已经不认识jar包了。

那么jar包到底是什么呢?它有哪些小秘密呢?一起来看一下吧。

jar包到底是什么

jar包其实是一种zip格式的文件,所以说你实际上是可以使用zip相关的命令来对jar包进行创建或者解压缩操作。

不同的是jar包中多了一个META-INF文件夹。

通过这个文件夹,jar包可以执行更多的操作。

JDK也自带了一个jar命令,通过jar命令我们可以实现创建,更新jar包的操作,下图是JDK8中jar命令的说明:

因为JDK9之后引入了模块化的概念,所以JDK9之后jar命令有了比较大的变化:

我们看一下JDK14中的jar命令的用法:

这里主要不是讲jar命令,所以我们不具体展开。

META-INF目录

jar包和zip包最大的区别就在于jar包中包含了META-INF目录(不是必须的),我们看一个比较常用的lombok.jar包的结构是怎么样的:

这个版本比较新,所以它使用的是最新的JPMS的写法,大家可以看到在jar包的根目录下面有一个module-info.class文件,表示这个jar包使用的是模块化。

然后再看一下META-INF目录,里面有一个MANIFEST.MF文件:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 14.3-b01-101 (Apple Inc.)
Premain-Class: lombok.launch.Agent
Agent-Class: lombok.launch.Agent
Can-Redefine-Classes: true
Main-Class: lombok.launch.Main
Lombok-Version: 1.18.10

MANIFEST.MF主要用来定义package相关的数据,这里我们可以看到lombok的MANIFEST.MF文件定义了manifest的版本号,创建时间,版本号和几个类型的class。

services文件夹里面存放的可以对外提供的服务。

这里列出的文件并不全,实际上还有下面几种文件:

INDEX.LIST

可以使用 -i在生成jar包的时候自动创建,是class的index文件,主要用来加速class加载。

x.SF

JAR包的签名文件。

x.DSA

与具有相同基本文件名的签名文件关联的签名块文件。该文件存储相应签名文件的数字签名。

versions/

主要为使用多版本的特性准备的,里面存储的是不同版本的class和资源。

比如下面命令创建了多个版本发行的jar包,并且将一些文件放在 META-INF/versions/9 目录中。

jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes

module-info.class

假如我们使用的是JDK9之后的JPMS模块化,那么就会生成这么一个module-info.class。这个文件主要是描述模块和外部模块直接的关系。

看一下lombok的例子:

module lombok {
    requires java.compiler;
    requires java.instrument;
    requires jdk.unsupported;
    requires static org.mapstruct.processor;


    exports lombok;
    exports lombok.experimental;
    exports lombok.extern.apachecommons;
    exports lombok.extern.java;
    exports lombok.extern.jbosslog;
    exports lombok.extern.log4j;
    exports lombok.extern.slf4j;
    exports lombok.extern.flogger;


    provides javax.annotation.processing.Processor with lombok.launch.AnnotationProcessorHider$AnnotationProcessor;
    provides org.mapstruct.ap.spi.AstModifyingAnnotationProcessor with lombok.launch.AnnotationProcessorHider$AstModificationNotifier;}

这里面我们定义了依赖的类和service providers,同时也定义了对外提供的类。

在JDK9之后,存在两种path,一种是之前的class path,一种是module path。当 modular JAR被部署在module path中的时候,它就是一个modular JAR。当他被部署在class path中的时候,就是一个non-modular JAR。

同样的,如果是一个non-modular JAR被定义在module path中,那么这个non-modular JAR就自动被转换成了一个automatic module。

如果jar包在MANIFEST.MF中定义了Automatic-Module-Name,那么module名字就是这个值,否则会从JAR的名字来定义这个module。

automatic module主要是为了向下兼容而产生的。

关于JPMS的更多信息可以参考我之前写的文章:JDK9的新特性:JPMS模块化.

versions

versions主要和 multi-release JAR一起使用的:

Multi-Release: true

所谓multi-release JAR就是说一个jar包可以支持不同版本的JDK。我们可以根据需要指定不同版本的JDK所依赖的class文件或者属性文件。这个特性在我们进行JDK升级的时候还是很有帮助的。

一般来说,目录结构是这样的:META-INF/versions/N

其中N表示的是JDK的主要发行版本,比如9,10,11等。

类加载器会先去META-INF/versions/N目录中加载所需要的class,然后会去其他的低版本的META-INF/versions/N目录中加载所需要的class,最后才会在META-INF/的根目录加载其他的class文件。

MANIFEST.MF详解

MANIFEST.MF中存放的是key:value格式的配置信息,这些配置信息又可以分成两部分,第一部分是main-p信息,第二部分是individual-p。

我们举个简单的例子:

Manifest-Version: 1.0
Created-By: 1.8 (Oracle Inc.)
Sealed: true
Name: foo/bar/
Sealed: false

其中

Manifest-Version: 1.0
Created-By: 1.8 (Oracle Inc.)
Sealed: true

就是main-p信息,我们用一张图来看一下main-p的信息有哪些:

在main-p信息下发可以接一个Name: Value,表示开启独立的针对于具体entry的属性(Per-Entry Attributes)配置:

Name: foo/bar/
Sealed: false

比如上面的属性是专门针对于包foo/bar/的,并且设置其Sealed属性为false。

Per-Entry Attributes除了 package versioning 和 sealing信息外,还可以定义Content-Type,Java-Bean,x-Digest-y和Magic属性。

JAR包签名

JAR包可以通过使用jarsigner来对其进行签名。和签名相关的文件是:

META-INF/MANIFEST.MF
META-INF/*.SF
META-INF/*.DSA
META-INF/*.RSA
META-INF/SIG-*

签名过后的jar跟原来的jar其实并没有什么不同,只不过在META-INF/文件夹中多出了两个文件,一个是签名文件,一个是签名block文件。

01

签名文件

签名文件是以.SF结尾的,这个文件和MANIFEST.MF很类似,可以指定Signature-Version和Created-By。

除此之外,还可以指定和安全相关的属性:

  • x-Digest-Manifest-Main-Attributes:其中x是java.security.MessageDigest中指定的算法,表示的主要属性的摘要。

  • x-Digest-Manifest:表示的是整个manifest的摘要。

这两个属性主要用来做验证签名用的。

举个例子:

如果我们的manifest是下面这样的:

   Manifest-Version: 1.0
    Created-By: 1.8.0 (Oracle Inc.)


    Name: common/class1.class
    SHA-256-Digest: (base64 representation of SHA-256 digest)


    Name: common/class2.class
    SHA1-Digest: (base64 representation of SHA1 digest)
    SHA-256-Digest: (base64 representation of SHA-256 digest)

那么相应的签名文件应该是这样的:

   Signature-Version: 1.0
    SHA-256-Digest-Manifest: (base64 representation of SHA-256 digest)
    SHA-256-Digest-Manifest-Main-Attributes: (base64 representation of SHA-256 digest)


    Name: common/class1.class
    SHA-256-Digest: (base64 representation of SHA-256 digest)


    Name: common/class2.class
    SHA-256-Digest: (base64 representation of SHA-256 digest)

02

签名文件的摘要

如果再对.SF文件进行摘要,那么就会得到签名文件的摘要文件:

.RSA (PKCS7 signature, SHA-256 + RSA)
.DSA (PKCS7 signature, DSA)

Sealed

上面我们讲到了一个Sealed属性:

Name: javax/servlet/internal/
Sealed: true

这个属性的意思是,javax/servlet/internal/包中的所有类必须从这个jar包中加载。

这个属性主要是从jar包的安全性来考虑的。

更多Java推文,可以关注下面公众号:Java后端编程 

关注回复:Java 获取学习资料

手把手教你解开图片的小秘密——图片隐写lab 解压得到result.png图片 题目提示LAB!LAB!所以是lab隐写,所以使用cmd进入Desktop输入java -jar Stegsolve.jar调用出(因为我放在桌面所以进入Desktop)。 使用过程中发现Red0、Green0、Blue0上面有隐藏信息 使用Data Extract勾选下图的配置,使用Save Bin保存为23.png得到一个二维码使用微信扫描即可得到SeBaFi{d7e1b86fdff38732d4a08907bada31e3} ... 阅读详情

相关推荐

spring cloud gateway 源码解析

Spring Cloud Gateway 是基于 Spring WebFlux 的响应式网关框架,其核心依赖 starter-gateway 和 starter-webflux。starter-webflux 使用 Reactor Netty 作为嵌入式反应式 HTTP 服务器,负责处理请求。通过分析源码,网关的启动过程涉及 ReactiveWebServerFactoryAutoConfiguration 和 NettyReactiveWebServerFactory,最终在 finishRefresh

renzhe1301的专栏 1144

jar包运行后显示 没有主清单属性

问题现象: jar包运行后显示 没有主清单属性! 问题分析: 1.缺少了项目maven插件 spring-boot-maven-plugin。 2. 没有指定具体的项目的Main入口。 解决方法: 方法1: https://blog.youkuaiyun.com/soulofball/article/details/107235369 方法2: https://blog.youkuaiyun.com/u011624972/article/details/58591825 ...

weixin_42585386的博客 6万+

Selenium Server Standalone 3.12.0自动化测试实战配置与使用指南

我们今天不仅仅讲了一个工具怎么用,更是完成了一次从表象到本质的技术探索之旅。我们知道了.jar文件其实是 ZIP;我们搞清楚了的真正作用;我们揪出了null.txt的源头;我们学会了如何安全清理并重建 JAR;我们掌握了 JVM 参数调优技巧;我们亲手搭建了一个完整的 Grid 集群。最重要的是,我们建立了一种思维方式:不要满足于“能跑就行”,要去追问“为什么能跑”。这种能力,在未来面对任何一个新技术栈时,都会成为你的核心竞争力。

weixin_36303305的博客 1161

在JAR文件中找不到主清单属性:原因与解决方案

在Java中,一个JAR文件通常包含一个名为的清单文件,这个文件定义了关于JAR文件的各种元数据。然而,有时我们可能会遇到一个问题,那就是在JAR文件中找不到主清单属性。

理论都是虚的,代码才是王道。 2万+

JAVA串口通信开发实战:RXTX库应用与串行数据读写

任何打开了的资源都必须关闭,否则会导致端口一直被占用,重启都救不了你……try {= null) {System.out.println("🔌 串口已安全关闭");System.err.println("关闭流失败: " + e.getMessage());建议结合或守护线程做自动回收。尽管RXTX项目已经多年未更新,但它依然是目前Java串口开发的事实标准。只要掌握了它的三大核心要点:分层架构理解跨平台部署技巧(DLL/SO/JNILIB放置位置)

weixin_33205138的博客 454

Spring Boot jar中没有主清单属性的解决方法

主要介绍了Spring Boot jar中没有主清单属性的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

【Java用法】jar包运行后显示 没有主清单属性

如果还是不行,就得查一下资料,看看自己项目中用到的springboot版本对应的打包插件配置,尤其是springboot3之后的版本,有很多配置有了很大的改变,本文章主要是用于适应大部分项目中使用的springboot2版本。把打包方式和打包插件添加到 pom.xml 文件中,然后 mvn clean 一下,再次重新打包,运行 jar 包,解决问题。文章中我的项目引用的父级依赖包是2.7.14版本的,亲测能正常打包,所以我的配置是没问题的。jar包运行后显示 没有主清单属性!

No8g攻城狮的博客 2万+

从0到1,快速理清 | DeepSeek Harness

DeepSeek推出自研Harness开发平台,主打"一切皆插件"理念,将AI执行能力模块化为可自由组合的插件体系。带你从0到1,快速了解开发链路。

IT学习博客 681

一文读懂jar包的小秘密

java程序员每天不是在创建jar包就是在创建jar包的路上,并且各种依赖引用都是以jar包的形式展示的。但是随着现代IDE的出现,我想很多程序员已经基本上很少直接和jar包打交道了。 换句话说,他们已经不认识jar包了。 那么jar包到底是什么呢?它有哪些小秘密呢?一起来看一下吧。

程序那些事 2万+

Versal - 从零构建Petalinux 2024.2 AI边缘计算平台(VD100+SDT+JupyterLab实战)

本文详细介绍了如何从零开始,基于AMD Versal VD100开发板和Petalinux 2024.2构建AI边缘计算平台。内容涵盖开发环境搭建、Petalinux工程创建与配置、SDT新流程实战、启动SD卡制作,并最终集成JupyterLab与Conda,打造出开箱即用的交互式AI开发环境,帮助开发者快速进行算法验证与部署。

5f4d3s2a1q的博客 489

【AI赋能】Sora + CapCut 打造爆款短视频:从脚本到发布的自动化工作流

本文详细介绍了如何利用Sora、Grok和CapCut等AI工具构建自动化短视频生产工作流。通过结构化Prompt生成专业脚本,借助Sora将文字转化为高质量视频素材,并利用CapCut进行高效剪辑与合成,实现从创意到发布的十倍效率提升,助力个人及团队打造爆款内容。

g8f9d0s1a2的博客 497

oracle中jar包在哪个文件夹,一文读懂jar包的小秘密

程序那些事简介java程序员每天不是在创建jar包就是在创建jar包的路上,并且各种依赖引用都是以jar包的形式展示的。但是随着现代IDE的出现,我想很多程序员已经基本上很少直接和jar包打交道了。换句话说,他们已经不认识jar包了。那么jar包到底是什么呢?它有哪些小秘密呢?一起来看一下吧。jar包到底是什么jar包其实是一种zip格式的文件,所以说你实际上是可以使用zip相关的命令来对jar包...

weixin_36139240的博客 2500

C# OpenCV机器视觉:红外体温检测

阿强长舒一口气,脸上露出了自信的笑容:“好了,万事俱备,只欠东风,接下来就看我的了!在这热图像里,不同的颜色代表着不同的温度区域,就好比一幅用温度绘制的抽象画,红色通常表示高温,蓝色则代表低温,通过解读这幅画,就能大致了解物体表面的温度分布情况。” 阿强兴奋得一拍大腿,“这不就像是找到了隐藏在黑暗中的线索,只要顺着这些红外线的踪迹,就能揪出体温异常的潜在风险,守护大家的健康啦。带着这份坚定的信念,阿强又投入到新的科技研发中,他相信,只要大家齐心协力,用科技点亮希望之光,就一定能迎来更加美好的明天。

xcwzj123的专栏 3152

jar包 jdk 停_一文读懂jar包的小秘密

简介java程序员每天不是在创建jar包就是在创建jar包的路上,并且各种依赖引用都是以jar包的形式展示的。但是随着现代IDE的出现,我想很多程序员已经基本上很少直接和jar包打交道了。换句话说,他们已经不认识jar包了。那么jar包到底是什么呢?它有哪些小秘密呢?一起来看一下吧。jar包到底是什么jar包其实是一种zip格式的文件,所以说你实际上是可以使用zip相关的命令来对jar包...

weixin_42386361的博客 119

【项目实战】Qt6 录制屏幕、录制声音生成MP4、AVI、MA3等(完整源码,可直接编译使用)

本文将详细介绍如何利用Qt6多媒体模块中的QMediaCaptureSession、QMediaRecorder、QScreenCapture、QAudioInput、QMediaFormat等功能,实现对屏幕和声音的录制,并生成常见的媒体格式文件,如MP4、AVI、MA3等。我们将探讨如何利用这些功能来实现灵活的视频和音频参数设置,以满足不同需求下的录制和生成要求。我们将重点讨论如何配置视频和音频参数,包括分辨率、帧率、编解码器选择、音频采样率、声道设置等。

yegu001的博客 4939

Tessent实战:网表扫描链插入全流程解析

本文详细解析了使用Tessent工具为网表插入扫描链(Scan Chain)的全流程。从前期环境配置、网表检查,到扫描链数量、时钟域等核心配置,再到执行扫描单元替换与连接,最后进行结果验证与文件输出。文章提供了关键命令与实用技巧,帮助工程师高效完成DFT设计,确保芯片可测试性。

hhh00的博客 747

jar中没有主清单属性_一文读懂jar包的小秘密

简介java程序员每天不是在创建jar包就是在创建jar包的路上,并且各种依赖引用都是以jar包的形式展示的。但是随着现代IDE的出现,我想很多程序员已经基本上很少直接和jar包打交道了。换句话说,他们已经不认识jar包了。那么jar包到底是什么呢?它有哪些小秘密呢?一起来看一下吧。jar包到底是什么jar包其实是一种zip格式的文件,所以说你实际上是可以使用zip相关的命令来对jar包进行创建或...

weixin_39866817的博客 183

推荐算法之Thompson(汤普森)采样

如果想理解汤普森采样算法,就必须先熟悉了解贝塔分布。 一、Beta(贝塔)分布 Beta分布是一个定义在[0,1]区间上的连续概率分布族,它有两个正值参数,称为形状参数,一般用α和β表示,Beta分布的概率密度函数形式如下: 这里的Γ表示gamma函数。 Beta分布的均值是: 方差: ...

weixin_30508241的博客 4259

.jar中没有主清单属性_一文读懂jar包的小秘密

简介java程序员每天不是在创建jar包就是在创建jar包的路上,并且各种依赖引用都是以jar包的形式展示的。但是随着现代IDE的出现,我想很多程序员已经基本上很少直接和jar包打交道了。换句话说,他们已经不认识jar包了。那么jar包到底是什么呢?它有哪些小秘密呢?一起来看一下吧。jar包到底是什么jar包其实是一种zip格式的文件,所以说你实际上是可以使用zip相关的命令来对jar包进行创建或...

weixin_39671964的博客 265

Agent Skills应用解析:构建可扩展、高效率AI探员

Agent Skills是一个简洁而强大的概念:它是一个包含组织化的指令、脚本和资源的文件夹,智能体可以动态地发现并加载这些内容,以在特定任务中表现更佳。可组合性(Composability):一个Agent Skill是一个独立的、封装良好的能力单元。开发者可以为不同的功能(例如PDF处理、网络浏览、数据分析)创建独立的技能,然后根据需要将它们组合起来,赋能不同的智能体。这意味着不再需要为每个用例构建碎片化、定制设计的智能体,而是可以通过组合现有技能来快速构建新的专业智能体。

形上得其象,形下合于数;阴阳自济,玄理自明。 1627

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

jar包的结构

jar包结构

qq_53318060的博客 1685

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Seed-VC 零样本语音转换使用指南

手里有一段录好的旁白,想换成别人的音色,可对方只有 10 秒参考音频,没法为每个人单独训练模型。传统变声方案每个说话人都要小时级语料。Seed-VC 是零样本语音转换项目,1~30 秒参考音频即可克隆音色,无需训练。它还支持实时与歌声转换,效果如何? ## 项目定位与核心差异 Seed-VC 面向想换音色、又不想为每个说话人单独训练的开发者,和 RVC/SoVITS 的本质差异是不训练、只靠参

gitblog_00535的博客 212

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

android.mk libs,从libs /添加一个jar文件到Android.mk

我的项目在libs /目录中包含commons-io-2.4.jar和jsch-0.1.49.jar。在月蚀中一切都很美妙。现在我想编写一个Android.mk文件来自动构建我的项目。我的Android.mk看起来像这样,但它不起作用。LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES := $(call all-java...

weixin_39729115的博客 174
上一篇: 史上首例!程序员写的代码,被国家博物馆收藏了!
下一篇: ​LeetCode刷题实战37: 解数独
编程IT圈
博客等级 码龄6年 1130粉丝 544原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值