失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Spring Boot Gradle 瘦身打包 thinJar 分离 lib jar 依赖

Spring Boot Gradle 瘦身打包 thinJar 分离 lib jar 依赖

时间:2021-04-19 11:34:09

相关推荐

Spring Boot Gradle 瘦身打包 thinJar 分离 lib jar 依赖

原文地址:weiku.co/article/135/ ,欢迎转载

需求背景:

srping boot 2.0+ 打包生产的fat jar虽然部署起来很方便,但将所有依赖都打包到一个 jar 包中使得体积也不小(40M+),第一次部署还没问题,之后的更新就很痛苦了,每次发布更新时一般都是自己项目的业务代码发生变化,依赖一般不会变化除非升级或增加了项目依赖。

我们期望的场景是每次更新只上传我们自己的业务模块 jar 包,大小可能只有几十K,这就是今天要讲的thin jar如何打包。

[scode type=“blue”]微酷今天研究了一天,终于找到一个很理想的方案,当然没少被折腾,每次都想放弃 Java 回头拥抱 C#,但还是坚持了下来。[/scode]

微酷研究了三个方案,推荐方案三。

方案一:

看起来非常的官方的方式,使用插件spring-boot-thin-launcher,使用起来也是相当的简单。

插件地址:[button color=“success” icon="" url=“/spring-projects-experimental/spring-boot-thin-launcher” type=“round”]点我点我[/button]

简单来说微酷对这个插件实现的理解:

插件可生成 pom.xml 或 thin.properties 文件保存项目所信赖的包。打包时只将自己项目打包,信赖项目不打包。启动时使用单独的装载器从 pom.xml 或 thin.properties 中读取信赖,然后从 maven 仓库下载依赖到本地。运行自己项目的 Main 函数。

安装:

配置build.gradle如下:

buildscript {ext {springBootVersion = '2.1.4.RELEASE'wrapperVersion = '1.0.21.RELEASE'}repositories {mavenCentral()}dependencies {classpath("org.springframework.boot.experimental:spring-boot-thin-gradle-plugin:${wrapperVersion}")classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")}}plugins {id "io.spring.dependency-management" version "1.0.7.RELEASE"}apply plugin: 'java'apply plugin: 'org.springframework.boot'apply plugin: 'io.spring.dependency-management'apply plugin: 'org.springframework.boot.experimental.thin-launcher'jar.dependsOn = [thinProperties]// 其它配置略...

配置上插件后就会在 Gradle 的 Tasks 中多出好多任务,都是以thin***开头的。

打包:

运行thinJar任务即可。生成的 jar 包在./build/thin/root下。

运行:

java -jar weiku-web-1.0.0.jar

[scode type=“yellow”]注意:第一次运行会有点慢,他会自己下载所需要的依赖。[/scode]

放弃:

下载依赖是微酷相当不喜欢的(虽然下载后可以缓存之后就不用再下载了),因为我本地有所依赖的所有 jar 包,为什么不让用的,并且一上午大把的时候都在研究这个问题最终也没找到答案,于是放弃这个方案了。

另外由于我的项目是多 module 于是引用的自己的依赖没有上传到 maven 仓库根本就找不到,所以我们项目最终也没有用这个方案运行成功。(可能有方法配置但我放弃继续研究了,英文不好的我的官方的 Readme 读了一遍已累爬。)

我的提问:/spring-projects-experimental/spring-boot-thin-launcher

方案二:

又找到一个方法,看起来是超级的简单。

标题:Spring Boot 用gradle bootJar打包瘦身(外置依赖jar)

原文:/formatkm/blog/1822900

方法二旧方法(原作者已经废弃):

网上 SpringBoot 打包瘦身的教程很多,但基本都是 Maven 的。一般公共库都外置,不需要打包进可执行的 jar 中,这样每次发布都不用传几十兆的文件。用 gradle 的 bootJar 实际很简单,方法就是把compile依赖替换为compileClasspathcompileClasspath

的依赖不会被打包进可运行的jar中。

//打包进jar//compile("org.springframework.boot:spring-boot-starter-freemarker")//只打包自己的代码compileClasspath("org.springframework.boot:spring-boot-starter-web")

另外可以用 complie 先配置好,导出依赖的jar到一个目录

task copyToLib(type: Copy) {into "$buildDir/libs/lib"from configurations.runtime}

导出后又改为compileClasspath

方法二的新方法:

修改bootJar如下,仅此而已:

bootJar {classifier = 'boot'excludes = ["*.jar"]}

运行的时候用-Djava.ext.dirs=指定依赖库的路径

java -Djava.ext.dirs=./lib -jar bootrun.jar

微酷实践:

微酷的项目用方案二的新方法能启动起来,大多数页面正常,但有的页面出错,如访问 MSSQL 数据库时出错:

服务器异常:驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“java.lang.RuntimeException: Could not generate DH keypair”。 ClientConnectionId:eb5aa5f7-8ed4-4bb0-99b8-a70a936640c5

针对这个问题搜索找到一个文章说:

-Djava.ext.dirs 会覆盖 Java 本身的 ext 设置,java.ext.dirs 指定的目录由 ExtClassLoader 加载器加载,如果您的程序没有指定该系统属性,那么该加载器默认加载 JAVAHOME/jre/lib/ext目录下的所有jar文件。但如果你手动指定系统属性且忘了把JAVA_HOME/jre/lib/ext 目录下的所有 jar 文件。但如果你手动指定系统属性且忘了把JAVAH​OME/jre/lib/ext目录下的所有jar文件。但如果你手动指定系统属性且忘了把JAVA_HOME/jre/lib/ext 路径给加上,那么 ExtClassLoader 不会去加载 $JAVA_HOME/lib/ext 下面的jar文件,这意味着你将失去一些功能,例如java自带的加解密算法实现。原文:/cyony/article/details/74375251

于是微酷将电脑C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext下的 13 个 jar 文件拷贝到项目发布后的libs目录中,竟然神奇的运行正常了。

其实应该继续研究如何合并两个位置的 jar 包来解决这个问题,那么就完美了。

但微酷又找到了完美的方案三,于是这个问题就不再继续研究了。

方案三(推荐):

又找到这种方法,看起来不错,运行时也不需要加java.ext.dirloader.path参数。

原标题:spring boot + gradle打包bootJar分离lib

原文:/georgeye/article/details/85318802

以前项目打包一直是用的 maven,最近新开一个项目,使用的是spring boot 2.11 + gradle 4.10.3,在打包的时候分离lib折腾了好几天,网上找了很多方法都不成功,老是卡在 pile 这里,总是获取不到正确的jar包路径。最后上google终于找到解决办法,总结整理后简单又好用,特此记录如下:

// 清除现有的lib目录task clearJar(type: Delete) {delete "$buildDir\\libs\\lib"}// 将依赖包复制到lib目录task copyJar(type: Copy, dependsOn: 'clearJar') {from pileClasspathinto "$buildDir\\libs\\lib"}bootJar {// 例外所有的jarexcludes = ["*.jar"]// lib目录的清除和复制任务 dependsOn clearJardependsOn copyJar// 指定依赖包的路径manifest {attributes "Manifest-Version": 1.0,'Class-Path': pileClasspath.files.collect { "lib/$it.name" }.join(' ')}}

运行的时候也不需要指定java.ext.dirloader.path了,直接-jar运行就可以了。

java -jar test-0.0.1-SNAPSHOT.jar

微酷实践:

但微酷加到项目中,运行出错:

A problem occurred evaluating project ‘:weiku-web’.

Cannot change dependencies of configuration ‘:weiku-web:compile’ after it has been included in dependency resolution.

解决:

找到这个文章:[button color=“warning” icon="" url=“/questions/42552511/cannot-change-dependencies-of-configuration-compile-after-it-has-been-resolve” type=“round”]点我点我[/button]

于是我尝试把我的dependencies放到了bootJar{}之前,竟然真的好了。

最终微酷整理的 build.gradle 文件:

buildscript {ext {springBootVersion = '2.1.4.RELEASE'}repositories {mavenCentral()}dependencies {classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")}}plugins {id "io.spring.dependency-management" version "1.0.7.RELEASE"}apply plugin: 'java'apply plugin: 'org.springframework.boot'apply plugin: 'io.spring.dependency-management'group 'co.weiku'version '1.0.0'repositories {mavenCentral()}dependencies {compile('org.springframework.boot:spring-boot-starter-web')compile group: 'com.microsoft.sqlserver', name: 'mssql-jdbc', version: '7.2.2.jre8'compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis', version: '2.1.4.RELEASE'compile group: 'mons', name: 'commons-pool2', version: '2.6.2'compile group: 'com.alibaba', name: 'druid', version: '1.1.16'compile group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc', version: '2.1.4.RELEASE'compile group: 'org.mybatis.spring.boot', name: 'mybatis-spring-boot-starter', version: '2.0.1'compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf', version: '2.1.4.RELEASE'compile group: 'org.apache.shiro', name: 'shiro-spring', version: '1.4.0'compile group: 'org.springframework.boot', name: 'spring-boot-devtools', version: '2.1.4.RELEASE'compile project(':weiku-framework')compile project(':weiku-common')}// 清除libtask myClearLib(type: Delete) {delete "$buildDir/libs/lib"}// 拷贝libtask myCopyLib(type: Copy) {into "$buildDir/libs/lib"from configurations.runtime}bootJar {//mainClassName = 'co.weiku.WeikuApplication'baseName = 'weiku-web'version = '1.0.0'classifier = 'boot'excludes = ["*.jar"]// lib目录的清除和复制任务dependsOn myClearLibdependsOn myCopyLib// 指定依赖包的路径,运行时不再需要指定 java.ext.dir 或 loader.path 参数。manifest {attributes "Manifest-Version": 1.0,'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' ')}}

这样运行 bootJar 任务后就会打包 thinJar 完成,并将信赖的 jar 包放在 lib 子目录下,运行测试成功。

完美收工。

如果觉得《Spring Boot Gradle 瘦身打包 thinJar 分离 lib jar 依赖》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。