可执行 jar 和普通 jar 区别

在我们的项目中使用IDEA可以将项目打包,可以打成可执行jar和普通的jar包,那么这两种jar有什么区别呢?

1.打包插件

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 呢?原因就是两种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 功能,其他功能要使用,则需要开发者显式配置。

2.打包

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

1.首先 mvn package 命令 对项目进行打包,打成一个 jar,这个 jar 就是一个普通的 jar,可以被其他项目依赖,但是不可以被执行。

2.repackage 命令,对第一步 打包成的 jar 进行再次打包,将之打成一个 可执行 jar ,通过将第一步打成的 jar 重命名为 *.original 文件。

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

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

这里有两个文件,第一个 springapplication-0.0.1-SNAPSHOT.jar 表示打包成的可执行 jar ,第二个 springapplication-0.0.1-SNAPSHOT.jar.original 则是在打包过程中 ,被重命名的 jar,这是一个不可执行 jar,但是可以被其他项目依赖的 jar。

通过对这两个文件的解压,我们可以看出这两者之间的差异。

3.两种 jar 的比较

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


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

Manifest-Version: 1.0
Implementation-Title: demo
Implementation-Version: 0.0.1-SNAPSHOT
Start-Class: com.allan.demo.DemoApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.1.8.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 文件。

3.2 不可执行 jar 解压之后

首先将默认的后缀 .original 除去,进行解压,目录如下:

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

Manifest-Version: 1.0
Implementation-Title: demo
Implementation-Version: 0.0.1-SNAPSHOT
Build-Jdk-Spec: 1.8
Created-By: Maven Archiver 3.4.0

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

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

4.一次打包两个 jar

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

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

 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><classifier>exec</classifier></configuration></plugin></plugins>
</build>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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

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

可执行 jar 和普通 jar 区别相关推荐

  1. Java连接SQL2005及SQL Server JDBC Driver 2.0中sqljdbc.jar和sqljdbc4.jar的区别

    第一.Java连接SQL2005 一.JAVA连接SQL的语句 JAVA连接SQL2000语句为: Class.forName("sun.jdbc.odbc.JdbcOdbcDriver&q ...

  2. java maven jar 打包_使用Maven打包可运行jar和javaagent.jar的区别

    简介 javaagent 是 Java1.5 之后引入的新特性,其主要作用是在class被加载之前对其拦截,以插入我们的字节码. java1.5 之前使用的是JVMTI(jvm tool interf ...

  3. SpringBoot 打成的 jar 包和普通的 jar 包有什么区别

    Spring Boot 中默认打包成的 jar 叫做可执行 jar,这种jar包可以通过可以通过命令(java -jar xxx.jar)来运行的,但这种jar包不能被其他项目所依赖,因为它和普通 j ...

  4. eclipse中几种加入jar包方式的区别

    Java中的Jar是如此的重要,以至于没有他们,我们就不能做出如此艺术的程序:封装.模块化.复用等等(无ant.marven方式) . 今天,我就来整理一些有关项目中的jar包添加管理的方法以及常见问 ...

  5. OJDBC版本区别 [ojdbc14.jar,ojdbc5.jar和ojdbc6.jar的区别]

    classes12.jar,ojdbc14.jar,ojdbc5.jar和ojdbc6.jar的区别,之间的差异 在使用Oracle JDBC驱动时,有些问题你是不是通过替换不同版本的Oracle  ...

  6. OJDBC驱动版本区别 [ojdbc14.jar,ojdbc5.jar跟ojdbc6.jar的区别]

    OJDBC版本区别 [ojdbc14.jar,ojdbc5.jar和ojdbc6.jar的区别] 在使用Oracle JDBC驱动时,有些问题你是不是通过替换不同版本的Oracle  JDBC驱动来解 ...

  7. OJDBC版本【classes12.jar,ojdbc14.jar,ojdbc5.jar和ojdbc6.jar的区别】

    classes12.jar,ojdbc14.jar,ojdbc5.jar和ojdbc6.jar的区别,之间的差异 在使用Oracle JDBC驱动时,有些问题你是不是通过替换不同版本的Oracle  ...

  8. java包 agent_使用Maven打包可运行jar和javaagent.jar的区别

    简介 javaagent 是 Java1.5 之后引入的新特性,其主要作用是在class被加载之前对其拦截,以插入我们的字节码. java1.5 之前使用的是JVMTI(jvm tool interf ...

  9. MYeclipse 或 eclipse中几种导入jar包方式的区别

    今天,我就来整理一些有关项目中的jar包添加管理的方法以及常见问题的解决: 1.jar导入到我们的web项目中的classpath下 1)这里呢,一种方法是,直接用MyEclipse里自带的相关的项目 ...

最新文章

  1. 了解java虚拟机—垃圾回收算法(5)
  2. 用微软安全工具加固网站安全 (URLScan Tool IIS Lock Tool)
  3. PostgreSQL · 特性介绍 · 全文搜索介绍
  4. windows域策略——配置组策略刷新间隔
  5. 果园机器人的写作思路_《果园机器人》三年级教学设计
  6. Windows 使用技巧之WinZIP密码破解
  7. Nifi 常用Processor
  8. 导轮式机器人_一种轮式机器人底盘的制作方法
  9. html b5纸尺寸,b5纸的大小?
  10. 外贸怎么开发客户?这些你不一定知道
  11. shell获取主机信息并根据定时任务发送邮件到手机
  12. D. 1.绿纹龙的森林游记
  13. C盘容量不足,怎么增加c盘空间?看这5个方法
  14. Hadoop入门 集群崩溃的处理方法
  15. 第一台生物计算机,世界上第一台DNA计算机问世
  16. 【转载】成本中心费用分配与分摊的区别
  17. 北大核心,CSSCI来源期刊(南大核心):《求索》|
  18. python k线顶分型_【交易技术】K线战法之『顶底分型』
  19. FPGA 历险记——xilinx MIG 使用(一)
  20. 大话数据结构(一)数据结构相关概念

热门文章

  1. COMPOSITE(组合)模式
  2. iot架构 mqtt netty_百度IoT:MQTT Broker架构设计
  3. Cesium 系列1 - 简介及源码下载发布
  4. 荣盛发展,或正在步华夏幸福后尘
  5. vue大文件上传控件选哪个好?
  6. Linux - 系统文件目录说明
  7. 11. 形态学膨胀、腐蚀、开运算、闭运算
  8. 激活函数的作用是什么?
  9. clearcase命令指南
  10. Wacom 数位板 和冠 手绘笔 Photoshop MacOS 延时卡顿丢笔解决办法