打包成单体 jar 包
在很多场景下,需要将程序及依赖打包为单个 jar 包,方便部署、运行。打包成单体 jar 包,有多个插件可选,比如 maven-shade-plugin
、maven-assembly-plugin
。
合并 META-INF/services
以 gRPC 为例,我们有一个依赖包,里面自定义了 NameResolver。
1 | META-INF/services/io.grpc.NameResolverProvider |
如果我们恰巧引用了另外一个依赖包(jetcd-core),里面定义了其他的 NameResolver。
1 | META-INF/services/io.grpc.NameResolverProvider |
那么,在我们打包成单体 jar 时,将两个依赖包内的 META-INF/services/io.grpc.NameResolverProvider
合并为一个,这样打包后的程序在运行时才可以通过 SPI 机制,找到所有的扩展。
1 | 期望的打包后 META-INF/services/io.grpc.NameResolverProvider |
无论 maven-shade-plugin
还是 maven-assembly-plugin
,默认配置都不支持合并,需要单独配置。
对于 maven-shade-plugin
,需要添加 transformer。
1 | <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> |
对于 maven-assembly-plugin
,需要添加组装描述文件 assembly.xml
,并启用 handler metaInf-services
。
1 | <!-- assembly.xml --> |
配置示例
maven-shade-plugin
和 maven-assembly-plugin
配置,二选一。
maven-shade-plugin
1 | <plugin> |
maven-assembly-plugin
1 | <plugin> |
assembly.xml
1 | <assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0" |
参考
- https://stackoverflow.com/questions/47310215/merging-meta-inf-services-files-with-maven-assembly-plugin
- https://segmentfault.com/a/1190000016237395
- https://stackoverflow.com/questions/38548271/difference-between-maven-plugins-assembly-plugins-jar-plugins-shaded-plugi
- https://github.com/apache/maven-assembly-plugin/blob/master/src/main/resources/assemblies/jar-with-dependencies.xml
- https://maven.apache.org/plugins/maven-shade-plugin/examples/executable-jar.html