前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Spring Boot2 系列教程(四十)Spring Boot 可执行 jar 分析

Spring Boot2 系列教程(四十)Spring Boot 可执行 jar 分析

作者头像
江南一点雨
发布于 2019-12-18 07:42:05
发布于 2019-12-18 07:42:05
1.5K00
代码可运行
举报
文章被收录于专栏:玩转JavaEE玩转JavaEE
运行总次数:0
代码可运行

前两天被人问到这样一个问题:

“松哥,为什么我的 Spring Boot 项目打包成的 jar ,被其他项目依赖之后,总是报找不到类的错误?”

大伙有这样的疑问,就是因为还没搞清楚可执行 jar 和普通 jar 到底有什么区别?今天松哥就和大家来聊一聊这个问题。

多了一个插件

Spring Boot 中默认打包成的 jar 叫做 可执行 jar,这种 jar 不同于普通的 jar,普通的 jar 不可以通过 java -jar xxx.jar 命令执行,普通的 jar 主要是被其他应用依赖,Spring Boot 打成的 jar 可以执行,但是不可以被其他的应用所依赖,即使强制依赖,也无法获取里边的类。但是可执行 jar 并不是 Spring Boot 独有的,Java 工程本身就可以打包成可执行 jar 。

有的小伙伴可能就有疑问了,既然同样是执行 mvn package 命令进行项目打包,为什么 Spring Boot 项目就打成了可执行 jar ,而普通项目则打包成了不可执行 jar 呢?

这我们就不得不提 Spring Boot 项目中一个默认的插件配置 spring-boot-maven-plugin ,这个打包插件存在 5 个方面的功能,从插件命令就可以看出:

五个功能分别是:

  • build-info:生成项目的构建信息文件 build-info.properties
  • repackage:这个是默认 goal,在 mvn package 执行之后,这个命令再次打包生成可执行的 jar,同时将 mvn package 生成的 jar 重命名为 *.origin
  • run:这个可以用来运行 Spring Boot 应用
  • start:这个在 mvn integration-test 阶段,进行 Spring Boot 应用生命周期的管理
  • stop:这个在 mvn integration-test 阶段,进行 Spring Boot 应用生命周期的管理

这里功能,默认情况下使用就是 repackage 功能,其他功能要使用,则需要开发者显式配置。

打包

repackage 功能的 作用,就是在打包的时候,多做一点额外的事情:

  1. 首先 mvn package 命令 对项目进行打包,打成一个 jar,这个 jar 就是一个普通的 jar,可以被其他项目依赖,但是不可以被执行
  2. repackage 命令,对第一步 打包成的 jar 进行再次打包,将之打成一个 可执行 jar ,通过将第一步打成的 jar 重命名为 *.original 文件

举个例子:

对任意一个 Spring Boot 项目进行打包,可以执行 mvn package 命令,也可以直接在 IDEA 中点击 package ,如下 :

打包成功之后, target 中的文件如下:

这里有两个文件,第一个 restful-0.0.1-SNAPSHOT.jar 表示打包成的可执行 jar ,第二个 restful-0.0.1-SNAPSHOT.jar.original 则是在打包过程中 ,被重命名的 jar,这是一个不可执行 jar,但是可以被其他项目依赖的 jar。通过对这两个文件的解压,我们可以看出这两者之间的差异。

两种 jar 的比较

可执行 jar 解压之后,目录如下:

可以看到,可执行 jar 中,我们自己的代码是存在 于 BOOT-INF/classes/ 目录下,另外,还有一个 META-INF 的目录,该目录下有一个 MANIFEST.MF 文件,打开该文件,内容如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Manifest-Version: 1.0
Implementation-Title: restful
Implementation-Version: 0.0.1-SNAPSHOT
Start-Class: org.javaboy.restful.RestfulApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.1.6.RELEASE
Created-By: Maven Archiver 3.4.0
Main-Class: org.springframework.boot.loader.JarLauncher

可以看到,这里定义了一个 Start-Class,这就是可执行 jar 的入口类,Spring-Boot-Classes 表示我们自己代码编译后的位置,Spring-Boot-Lib 则表示项目依赖的 jar 的位置。

换句话说,如果自己要打一个可执行 jar 包的话,除了添加相关依赖之外,还需要配置 META-INF/MANIFEST.MF 文件。

这是可执行 jar 的结构,那么不可执行 jar 的结构呢?

我们首先将默认的后缀 .original 除去,然后给文件重命名,重命名完成,进行解压:

解压后可以看到,不可执行 jar 根目录就相当于我们的 classpath,解压之后,直接就能看到我们的代码,它也有 META-INF/MANIFEST.MF 文件,但是文件中没有定义启动类等。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Manifest-Version: 1.0
Implementation-Title: restful
Implementation-Version: 0.0.1-SNAPSHOT
Build-Jdk-Spec: 1.8
Created-By: Maven Archiver 3.4.0

注意

这个不可以执行 jar 也没有将项目的依赖打包进来。

从这里我们就可以看出,两个 jar ,虽然都是 jar 包,但是内部结构是完全不同的,因此一个可以直接执行,另一个则可以被其他项目依赖。

一次打包两个 jar

一般来说,Spring Boot 直接打包成可执行 jar 就可以了,不建议将 Spring Boot 作为普通的 jar 被其他的项目所依赖。如果有这种需求,建议将被依赖的部分,单独抽出来做一个普通的 Maven 项目,然后在 Spring Boot 中引用这个 Maven 项目。

如果非要将 Spring Boot 打包成一个普通 jar 被其他项目依赖,技术上来说,也是可以的,给 spring-boot-maven-plugin 插件添加如下配置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <classifier>exec</classifier>
            </configuration>
        </plugin>
    </plugins>
</build>

配置的 classifier 表示可执行 jar 的名字,配置了这个之后,在插件执行 repackage 命令时,就不会给 mvn package 所打成的 jar 重命名了,所以,打包后的 jar 如下:

第一个 jar 表示可以被其他项目依赖的 jar ,第二个 jar 则表示一个可执行 jar。

好了,关于 Spring Boot 中 jar 的问题,我们就说这么多,有问题欢迎留言讨论。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 江南一点雨 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
情人节程序员用HTML网页表白【告白展示墙】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript
1 网页简介:基于 HTML+CSS+JavaScript 制作七夕情人节表白网页、生日祝福、七夕告白、 求婚、浪漫爱情3D相册、炫酷代码 ,快来制作一款高端的表白网页送(他/她)浪漫的告白,制作修改简单,可自行更换背景音乐,文字和图片即可使用
IT司马青衫
2022/08/20
1.2K0
情人节程序员用HTML网页表白【告白展示墙】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript
python open 函数指定编码为 ansi 的方法
在Python中,当使用open函数打开文件时,可以通过encoding参数来指定文件的编码方式。然而,需要注意的是,Python标准库中的编码并不直接支持名为”ANSI”的编码,因为”ANSI”在不同的系统和地区可能代表不同的编码(如Windows平台上的GBK、GB2312、Big5等)。
Power
2025/04/02
790
真棒!彻底解决了一直困扰的编码问题
在批量处理文件(后缀包括 ".csv"、".xlsx"、".xls"的文件)时,可能会出现同一个文件夹内同时存在不同编码的文件;亦或非"utf-8"格式的其他格式,即便相同格式也会出现有些文件能打开,而有些文件不能打开。
数据STUDIO
2021/06/24
1.2K0
计算机的字符与编码集
很多应用或国家中的符号都无法表示,比如数学符号 ÷≠≥≈π,第一次对ASCII码进行扩充, 7bits => 8bits
JavaEdge
2021/02/23
5020
计算机的字符与编码集
java编译报错提示编码GBK的不可映射字符啥意思_java字符串编码转换
原因: java程序在编译的时候,需要使用JDK开发工具包中的JAVAC.EXE命令,而JDK开发工具包是国际版的,默认格式为UNICODE的编码格式。因此在默认情况下,javac.exe会采用默认的编码格式,什么是默认的编码格式呢?也就是我们在编译JAVA程序时,在未指定源程序文件的编码格式的情况下,JDK会优先获取操作系统的file.encoding参数,然后JDK就把我们的JAVA源程序从file.encoding编码格式转化为JAVA内部默认的UNICODE格式放到内存中。然后,javac把转换后的UNICODE格式的文件进行编译成class类文件,此时.class文件是UNICODE编码的,它暂放在内存中,之后,JDK将此以UNICODE编码编译后的.class文件保存到操作系统中形成我们见到的.class文件;
全栈程序员站长
2022/09/30
2K0
java编译报错提示编码GBK的不可映射字符啥意思_java字符串编码转换
java中byte, iso-8859-1, UTF-8,乱码的根源
Post@https://ryan-miao.github.io 测试代码https://github.com/Ryan-Miao/someTest/commit/50241e50d4b6ecdb8820e58f4cb9628bfb7d77ec 背景 还是多语言, 在项目中遇到本地环境和服务端环境不一致乱码的情形。因此需要搞清楚乱码产生的过程,来分析原因。 获取多语言代码如下: private Map<String, String> getLocalizationContent(Locale locale
Ryan-Miao
2018/03/13
3.2K0
java中byte, iso-8859-1, UTF-8,乱码的根源
架构师必须掌握的各种编码:ASCII、ISO-8859-1、GB2312...
编码在我们日常开发过程中经常有遇到,常见的编码格式有ASCII、ISO-8859-1、GB2312、GBK、GB18030、UNICODE、UTF-8、UTF-16等,其中GB2312、GBK、GB18030、UTF-8、UTF-16都可以用来表示中文,那么哪种存储中文会比较合适呢,下面会对这几种编码一一介绍便会有结论。 为什么有编码 我们知道计算机中最小的存储单位是字节(byte),一个字节所能表示的字符数又有限,1byte=8bit,一个字节最多也只能表示255个字符,而世界上的语种又多,都有各种不
Java技术栈
2018/03/30
2.2K0
Java Web中的中文编码问题分析
在计算机中存储信息的最小单位是1个字节,即8bit,所以能标识的最大字符范围是0~255,而人类自然语言中例如汉语、日语要表示的符号太多,无法单纯用一个字节来完全表示,为了解决这个矛盾必须要有一个新的人类可识别的数据存储结构字符,而从char到byte必须编码。
用户9184480
2024/12/19
1160
Java Web中的中文编码问题分析
万字长文总结JAVA几种常见的编码格式和乱码原因分析
编码问题一直困扰着开发人员,尤其在 Java 中更加明显,因为 Java 是跨平台语言,不同平台之间编码之间的切换较多。本文将向你详细介绍 Java 中编码问题出现的根本原因,你将了解到:Java 中经常遇到的几种编码格式的区别;Java 中经常需要编码的场景;出现中文问题的原因分析;在开发 Java web 程序时可能会存在编码的几个地方,一个 HTTP 请求怎么控制编码格式?如何避免出现中文问题?
业余草
2021/02/04
1K0
万字长文总结JAVA几种常见的编码格式和乱码原因分析
Python-基础05-字符编码
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
DriverZeng
2022/09/26
6190
Python-基础05-字符编码
编码漫谈
Unicode用数字0-0x10FFFF来映射字符,最多可以容纳1114112个字符,或者说有1114112个码位,理论上是足够用的。
老高的技术博客
2022/12/27
2800
编码漫谈
帮你彻底弄懂常见的中文字符编码
| 导语 本文主要介绍了业务中常见的ASCII、GB2312、GBK、GB18030、UTF8、ANSI、Latin1中文编码。如果你在业务中也曾经被乱码搞晕过,不妨我们一起探究一下。 PS:文末有今天儿童节粉丝福利活动哦! 最近我的业务中涉及到了包含中文文本的内容解析。业务场景是用户上传一个包含中文的文本文件,我们需要根据约定好的字段格式解析该文本,并将内容导入到数据库中。但用户所传上来的文件中文编码经常会不一样,于是我们的数据库中经常会有乱码出现。为了解决该问题,就有了这篇文章…… 1、字符编码要做
腾讯NEXT学位
2020/06/02
3.4K0
字符编码技术专题(一):快速理解ASCII、Unicode、GBK和UTF-8
今天中午,我突然想搞清楚 Unicode 和 UTF-8 之间的关系,就开始查资料。
JackJiang
2023/09/27
2.6K0
字符编码技术专题(一):快速理解ASCII、Unicode、GBK和UTF-8
刨根究底字符编码之五——简体汉字编码方案(GB2312、GBK、GB18030、GB13000)以及全角、半角、CJK
英文字母再加一些其他标点字符之类的也不会超过256个,用一个字节来表示一个字符就足够了(2^8 = 256)。但其他一些文字不止这么多字符,比如中文中的汉字就多达10多万个,一个字节只能表示256个字符,肯定是不够的,因此只能使用多个字节来表示一个字符。
笨笨阿林
2022/05/09
4K0
刨根究底字符编码之五——简体汉字编码方案(GB2312、GBK、GB18030、GB13000)以及全角、半角、CJK
python字符串编码及乱码解决方案
http://blog.csdn.net/pipisorry/article/details/44136297
全栈程序员站长
2022/09/06
2.2K0
python字符串编码及乱码解决方案
字符、字符集、编码,以及它们python中会遇到的一些问题(下)
在看了很多的博客文章之后,总结整理得到了以下文章,非常感谢这些无私奉献的博主! 文章末尾有本文引用的文章的链接,如果有漏掉的文章引用,可以发邮件联系我,随后再次附上链接! 侵删!!! 这一部分是下篇,主要讲的是编码部分,以及在python中会遇到的一些编码问题,偏向于实际应用一点。 上篇介绍了字符、字符集的一些概念,以及他们在python中的一些简单的代码示例,偏向于概念。 上篇地址:http://www.cnblogs.com/echo-coding/p/7435118.html 这绝对是个源
Echo_fy
2018/06/20
2K0
‘gbk’ codec cant decode byte_can’t的完整形式
【报错】UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0x80 in position 13: illegal multibyte sequence
全栈程序员站长
2022/10/02
6490
‘gbk’ codec cant decode byte_can’t的完整形式
codeblocks中文编码问题
其实这是老调重弹的问题了,在windows下面出现中文乱码大多都是编码格式的问题不一致的问题,最简单的就是uft-8和gbk冲突的问题。如果一个文件本来是以utf-8存的,但是以gbk打开,当然会出现乱码了。
全栈程序员站长
2022/09/19
3.1K1
codeblocks中文编码问题
基于Windows下处理Java错误:编码GBK的不可映射字符的解决方案
基于Windows下处理Java错误:编码GBK的不可映射字符的解决方案 最近在研究Java,涉及命令行编译,使用notepad++编辑器,然后使用javac编译; 之前的几个文件没有中文的内容,都没
Angel_Kitty
2018/04/09
1.5K0
基于Windows下处理Java错误:编码GBK的不可映射字符的解决方案
你所不了解的字符编码
前言 在我的工作中,常常会遇到形形色色的字符编码,对于各种编码技术本人了解的也不是很多。 本篇是我了解编码系列的开篇,主要内容讲述字符编码的基本概念,然后介绍一下常见的字符编码,最后说明一下 Java
BUG弄潮儿
2021/06/25
1K0
你所不了解的字符编码
推荐阅读
相关推荐
情人节程序员用HTML网页表白【告白展示墙】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文