首页 » Web前端 » PHP紧缩jar文件技巧_Java 打包 FatJar 方法小结

PHP紧缩jar文件技巧_Java 打包 FatJar 方法小结

访客 2024-12-17 0

扫一扫用手机浏览

文章目录 [+]

一个正常的 java 程序会有多少个.class 文件和所依赖的第三方库的 jar 文件组成。

1. 非遮蔽方法(Unshaded)

PHP紧缩jar文件技巧_Java 打包 FatJar 方法小结

非遮蔽是相对付遮蔽而说的,可以理解为一种朴素的办法。
解压所有 jar 文件,再重新打包成一个新的单独的 jar 文件。

PHP紧缩jar文件技巧_Java 打包 FatJar 方法小结
(图片来自网络侵删)

借助 Maven Assembly Plugin 都可以轻松实现非遮蔽方法的打包。

Maven Assembly Plugin

Maven Assembly Plugin 是一个打包聚合插件,其紧张功能是把项目的编译输出协同依赖,模块,文档和其他文件打包成一个独立的发布包。
利用描述符(descriptor)来配置须要打包的物料组合。
并预定义了常用的描述符,可供直策应用。

预定义描述符如下

bin 只打包编译结果,并包含 README, LICENSE 和 NOTICE 文件,输出文件格式为 tar.gz, tar.bz2 和 zip。
jar-with-dependencies 打包编译结果,并带上所有的依赖,如果依赖的是 jar 包,jar 包会被解压开,平铺到终极的 uber-jar 里去。
输出格式为 jar。
src 打包源码文件。
输出格式为 tar.gz, tar.bz2 和 zip。
project 打包全体项目,除了支配输出目录 target 以外的所有文件和目录都会被打包。
输出格式为 tar.gz, tar.bz2 和 zip。

除了预定义的描述符,用户也可以指定描述符,以知足不同的打包需求。

打包成 uber-jar,须要利用预定义的 jar-with-dependencies 描述符:

在 pom.xml 中加入如下配置

Gradle Java plugin

gradle 下打包一个非遮蔽的 jar 包,有不少插件可以用,但是由于 gradle 自身的灵巧性,可以直接用 groove 的 dsl 实现。

非遮蔽方法会把所有的 jar 包里的文件都解压到一个目录里,然后在打包同一个 fatjar 中。
对付繁芜运用很可能会碰到同名类相互覆盖问题。

2. 遮蔽方法(Shaded)

遮蔽方法会把依赖包里的类路径进行修正到某个子路径下,这样可以一定程度上避免同名类相互覆盖的问题。
终极发布的 jar 也不会带入通报依赖冲突问题给下贱。

Maven Shade Plugin

在 pom.xml 中加入如下配置

Gradle Shadow plugin

Gradle shadow plugin 利用非常大略,大略声明插件后就可以生效。

遮蔽方法依赖修正 class 的字节码,更新依赖文件的包路径达到规避同名同包类冲突的问题,但是改名也会带来其他问题,比如代码中利用 Class.forName 或 ClassLoader.loadClass 装载的类,Shade Plugin 是感知不到的。
同名文件覆盖问题也没法杜绝,比如META-INF/services/javax.script.ScriptEngineFactory不属于类文件,但是被覆盖后会涌现问题。

3. 嵌套方法(Jar of Jars)

还是一种办法便是在 jar 包里嵌套其他 jar,这个方法可以彻底避免解压同名覆盖的问题,但是这个方法不被 JVM 原生支持,由于 JDK 供应的 ClassLoader 仅支持装载嵌套 jar 包的 class 文件。
以是这种方法须要自定义 ClassLoader 以支持嵌套 jar。

Onejar Maven Plugin

One-JAR 便是一个基于上面嵌套 jar 实现的工具。
onejar-maven-plugin 是社区基于 onejar 实现的 maven 插件。

Spring boot plugin

One-JAR 有点年久失落修,好久没有掩护了,Spring Boot 供应的 Maven Plugin 也可以打包 Fatjar,支持非遮蔽和嵌套的稠浊模式,并且支持 maven 和 gradle 。

requiresUnpack 参数可以定制那些 jar 不肯望被解压,采取嵌套的办法打包到 Fatjar 内部。

其打包后的内部构造为

运用的类文件被放置到 BOOT-INF/classes 目录,依赖包被放置到 BOOT-INF/lib 目录。

查看 META-INF/MANIFEST.MF 文件,其内容为

启动类是固定的 org.springframework.boot.loader.JarLauncher,运用程序的入口类须要配置成 Start-Class。
这样做的目的紧张是为了支持嵌套 jar 包的类装载,更换掉默认的 ClassLoader。

但是函数打算 Java Runtime 须要的 jar 包是一种打包构造,在做事端运行时会解压开,./lib 目录加到 classpath 中,单不会调用 Main-Class。
以是自定义 ClassLoader 是不生效的,以是不要利用嵌套 jar 构造,除非在入口函数指定重新定义 ClassLoader 或者 classpath 以支持 BOOT-INF/classes 和 BOOT-INF/lib 这样的定制化的类路径。

小结

插件 构建平台 事情机制 maven-assembly-plugin maven Unshaded Gradle Java plugin gradle Unshaded maven-shade-plugin maven Shaded com.github.johnrengelman.shadow gradle Shaded Onejar ant, maven Jar of Jars Spring boot plugin maven, gradle Unshaded, Jar of Jars 单从 Fatjar 的角度看, Spring boot maven/gradle 做得最精细。
但是 jar 包内部的自定义路径解压开往后和函数打算是不兼容的。
以是如果用于函数打算打包,建议利用 Unshaded 或者 Shared 的打包办法,但是须要自己把稳文件覆盖问题。

作者:倚贤

标签:

相关文章