• 沒有找到結果。

J a v a 打 包 F a t J a r ⽅ 法 ⼩ 结

N/A
N/A
Protected

Academic year: 2021

Share "J a v a 打 包 F a t J a r ⽅ 法 ⼩ 结"

Copied!
5
0
0

加載中.... (立即查看全文)

全文

(1)

Java 打包 FatJar ⽅法⼩结

阿⾥云云栖社区

. . . 字数 , 阅读 ,

在函数计算(Aliyun FC)中发布⼀个 Java 函数,往往需要将函数打包成⼀个 all-in-one 的 zip 包或 者 jar 包。Java 中这种打包 all-in-one 的技术常称之为 Fatjar 技术。本⽂⼩结⼀下 Java ⾥打包 FatJar 的若⼲种⽅法。

什么是 FatJar

FatJar ⼜称作 uber-Jar,是包含所有依赖的 Jar 包。Jar 包中嵌⼊了除 java 虚拟机以外的所有依 赖。我们知道 Java 的依赖分为两种, 零散的 .class ⽂件和把多个 .class ⽂件以 zip 格式打包⽽

成 jar ⽂件。FatJar 是⼀个 all-in-one Jar 包。FatJar 技术可以让那些⽤于最终发布的 Jar 便于部 署和运⾏。

三种打包⽅法

我们知道 .java 源码⽂件会被编译器编译成字节码.class ⽂件。Java 虚拟机执⾏的是 .class ⽂ 件。⼀个 java 程序可以有很多个 .class⽂件。这些 .class ⽂件可以由 java 虚拟机的类装载器运⾏

期装载到内存⾥。java 虚拟机可以从某个⽬录装载所有的 .class ⽂件,但是这些零散的.class ⽂ 件并不便于分发。所有 java ⽀持把零散的.class ⽂件打包成 zip 格式的 .jar ⽂件,并且虚拟机的 类装载器⽀持直接装载 .jar ⽂件。

⼀个正常的 java 程序会有若⼲个.class ⽂件和所依赖的第三⽅库的 jar ⽂件组成。

. ⾮遮蔽⽅法(Unshaded)

⾮遮蔽是相对于遮蔽⽽说的,可以理解为⼀种朴素的办法。解压所有 jar ⽂件,再重新打包成⼀

个新的单独的 jar ⽂件。

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

Maven Assembly Plugin

Maven Assembly Plugin 是⼀个打包聚合插件,其主要功能是把项⽬的编译输出协同依赖,模 块,⽂档和其他⽂件打包成⼀个独⽴的发布包。使⽤描述符(descriptor)来配置需要打包的物 料组合。并预定义了常⽤的描述符,可供直接使⽤。

预定义描述符如下

• bin 只打包编译结果,并包含 README, LICENSE 和 NOTICE ⽂件,输出⽂件格式为 tar.gz, tar.bz 和 zip。

• jar-with-dependencies 打包编译结果,并带上所有的依赖,如果依赖的是 jar 包,jar 包会被 解压开,平铺到最终的 uber-jar ⾥去。输出格式为 jar。

• src 打包源码⽂件。输出格式为 tar.gz, tar.bz 和 zip。

• project 打包整个项⽬,除了部署输出⽬录 target 以外的所有⽂件和⽬录都会被打包。输出格式 为 tar.gz, tar.bz 和 zip。

除了预定义的描述符,⽤户也可以指定描述符,以满⾜不同的打包需求。

打包成 uber-jar,需要使⽤预定义的 jar-with-dependencies 描述符:

在 pom.xml 中加⼊如下配置

关注

(2)

Gradle Java plugin

gradle 下打包⼀个⾮遮蔽的 jar 包,有不少插件可以⽤,但是由于 gradle ⾃身的灵活性,可以直 接⽤ groove 的 dsl 实现。

⾮遮蔽⽅法会把所有的 jar 包⾥的⽂件都解压到⼀个⽬录⾥,然后在打包同⼀个 fatjar 中。

对于复杂应⽤很可能会碰到同名类相互覆盖问题。

. 遮蔽⽅法(Shaded)

遮蔽⽅法会把依赖包⾥的类路径进⾏修改到某个⼦路径下,这样可以⼀定程度上避免同名类相互 覆盖的问题。最终发布的 jar 也不会带⼊传递依赖冲突问题给下游。

Maven Shade Plugin 在 pom.xml 中加⼊如下配置

Gradle Shadow plugin

Gradle shadow plugin 使⽤⾮常简单,简单声明插件后就可以⽣效。

(3)

遮蔽⽅法依赖修改 class 的字节码,更新依赖⽂件的包路径达到规避同名同包类冲突的问 题,但是改名也会带来其他问题,⽐如代码中使⽤ Class.forName 或

ClassLoader.loadClass 装载的类,Shade Plugin 是感知不到的。同名⽂件覆盖问题也没法 杜绝,⽐如META-INF/services/javax.script.ScriptEngineFactory不属于类⽂件,但是被覆 盖后会出现问题。

. 嵌套⽅法(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 。

(4)

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 这样的定制化的类路径。

⼩结

单从 Fatjar 的⻆度看, Spring boot maven/gradle 做得最精致。但是 jar 包内部的⾃定义路径解 压开以后和函数计算是不兼容的。所以如果⽤于函数计算打包,建议使⽤ Unshaded 或者 Shared 的打包⽅式,但是需要⾃⼰注意⽂件覆盖问题。

本⽂作者:倚贤 阅读原⽂

(5)

本⽂为云栖社区原创内容,未经允许不得转载。

參考文獻

相關文件

•Q :依據討論出的檢核標 準,評核這些組的內容.. •小組討論 (

Place the code elements in order so that the resulting Java source file will compile correctly, resulting in a class called “com.sun.cert.AddressBook”。..

[r]

Numerical experiments are done for a class of quasi-convex optimization problems where the function f (x) is a composition of a quadratic convex function from IR n to IR and

A subgroup N which is open in the norm topology by Theorem 3.1.3 is a group of norms N L/K L ∗ of a finite abelian extension L/K.. Then N is open in the norm topology if and only if

Since the generalized Fischer-Burmeister function ψ p is quasi-linear, the quadratic penalty for equilibrium constraints will make the convexity of the global smoothing function

Moreover, for the merit functions induced by them for the second-order cone complementarity problem (SOCCP), we provide a condition for each stationary point being a solution of

Moreover, for the merit functions induced by them for the second- order cone complementarity problem (SOCCP), we provide a condition for each sta- tionary point to be a solution of