URL
date
AI summary
slug
status
tags
summary
type

前言

生成可执行jar包的方式有很多,其中比较值得注意的地方就是对于依赖包的处理。按照依赖包的处理方式,大致可以分成三种类型:
  1. 暴力型——把依赖包都解压出来,然后打包到新的可执行jar包里
  1. 半优雅型——把依赖包原封不动的copy到可执行jar包的附近(比如同级目录或者是lib目录下),然后通过可执行jar包的manifest文件指定classpath关联
  1. 优雅型——也就是通常说的fatjar或者uberjar,这种方式是把依赖包全部被copy到可执行jar包里,成为fatjar。然后通过自定义的classloader以及URLStreamHandler来实现能读取到依赖包里的类以及资源文件
下面我们就来看看每种类型对应的一些具体的生成方式。每一种生成方式都已经上传到Github,可以直接下到本地执行。
how-to-build-executable-jar
zhuchao941Updated Jul 19, 2023

暴力型

maven-assembly-plugin

上面这篇文章演示了一个简单的demo,这里就不再赘述了。这里就提一点,文中也有提到
Maven assembly plugin is not good in producing fat/uber jar, it may cause name conflict issue, it is better to use other Maven plugins like :
1. Maven shade plugin solve this by using technique like class relocating.
2. Maven one-jar plugin, add the dependency jar file directly into project jar, and loads it with custom class loader.
意思就是,maven-assembly-plugin可能没有什么好的方案来解决jar包冲突的问题。因为maven-assembly-plugin是暴力型的方式,如果出现jar包冲突的话,也只能保留其中一个。
这里也引出了另外两种打包方案——maven-shard-pluginmaven-onejar-plugin

maven-shard-plugin

这个插件相比于maven-assembly-plugin,多了一个class relocating功能,可以把冲突的jar包或者说冲突的类通过重命名(class relocating)的方式来解决冲突问题。
同样也已经有完整的demo演示了,这里也不再赘述。
另外,下面这篇文章提供了一个通过maven-shard-plugin来解决jar包冲突的实际场景,有助于理解class relocating。

半优雅型

maven-jar-plugin + maven-dependency-plugin

这种方式需要2个插件配合:
  • maven-dependency-plugin负责把依赖包copy到指定的路径
  • maven-jar-plugin负责打包目标项目,生成对应的manifest文件并指定classpath为maven-dependency-plugin copy依赖包指定的路径

优雅型

onejar-maven-plugin

这个插件的用法也有对应的demo
不过这个代码已经运行不起来了,直接用我demo的代码跑就可以了

spring-boot-maven-plugin

因为springboot的普及,这个应该是大家最常用的插件了。大家直接参考demo里的demo就可以了
那么优雅型的jar包是怎么运行的呢?在jar包里的依赖包又是怎么添加到classpath的?后面会有单独的文章来讲。这不是本篇文章的侧重点。

IntelliJ IDEA 创建可执行jar包

还可以使用开发工具来创建可执行jar包,既支持暴力型,也支持半优雅型。另外一篇blog有完整的创建步骤
shardingsphere-proxy和流式查询通过IntelliJ IDEA 创建可执行jar包