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=“https://github.com/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 读了一遍已累爬。)
我的提问:https://github.com/spring-projects-experimental/spring-boot-thin-launcher
方案二:
又找到一个方法,看起来是超级的简单。
标题:Spring Boot 用gradle bootJar打包瘦身(外置依赖jar)
原文:https://my.oschina.net/formatkm/blog/1822900
方法二旧方法(原作者已经废弃):
网上 SpringBoot 打包瘦身的教程很多,但基本都是 Maven 的。一般公共库都外置,不需要打包进可执行的 jar 中,这样每次发布都不用传几十兆的文件。用 gradle 的 bootJar 实际很简单,方法就是把 compile
依赖替换为 compileClasspath
。 compileClasspath
的依赖不会被打包进可运行的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 文件。但如果你手动指定系统属性且忘了把JAVAHOME/jre/lib/ext目录下的所有jar文件。但如果你手动指定系统属性且忘了把JAVA_HOME/jre/lib/ext 路径给加上,那么 ExtClassLoader 不会去加载 $JAVA_HOME/lib/ext 下面的jar文件,这意味着你将失去一些功能,例如java自带的加解密算法实现。原文:https://blog.csdn.net/cyony/article/details/74375251
于是微酷将电脑C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext
下的 13 个 jar 文件拷贝到项目发布后的 libs
目录中,竟然神奇的运行正常了。
其实应该继续研究如何合并两个位置的 jar 包来解决这个问题,那么就完美了。
但微酷又找到了完美的方案三,于是这个问题就不再继续研究了。
方案三(推荐):
又找到这种方法,看起来不错,运行时也不需要加 java.ext.dir
或 loader.path
参数。
原标题:spring boot + gradle打包bootJar分离lib
原文:https://blog.csdn.net/georgeye/article/details/85318802
以前项目打包一直是用的 maven,最近新开一个项目,使用的是spring boot 2.11 + gradle 4.10.3,在打包的时候分离lib折腾了好几天,网上找了很多方法都不成功,老是卡在 configurations.compile 这里,总是获取不到正确的jar包路径。最后上google终于找到解决办法,总结整理后简单又好用,特此记录如下:
// 清除现有的lib目录
task clearJar(type: Delete) {delete "$buildDir\\libs\\lib"
}// 将依赖包复制到lib目录
task copyJar(type: Copy, dependsOn: 'clearJar') {from configurations.compileClasspathinto "$buildDir\\libs\\lib"
}bootJar {// 例外所有的jarexcludes = ["*.jar"]// lib目录的清除和复制任务 dependsOn clearJardependsOn copyJar// 指定依赖包的路径manifest {attributes "Manifest-Version": 1.0,'Class-Path': configurations.compileClasspath.files.collect { "lib/$it.name" }.join(' ')}
}
运行的时候也不需要指定 java.ext.dir
或 loader.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=“https://stackoverflow.com/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: 'org.apache.commons', 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')
}// 清除lib
task myClearLib(type: Delete) {delete "$buildDir/libs/lib"
}// 拷贝lib
task 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 依赖相关推荐
- Spring Boot项目瘦身
目录 1,什么是瘦身? 2,为什么要瘦身? 3,如何瘦身? 3.1,瘦身思路: 3.2,瘦身方法 4,瘦身后运行 1,什么是瘦身? 瘦身:thinBody,又称"减肥"." ...
- Spring Boot 项目瘦身指南,瘦到不可思议!129M->1.3M
之前在 从使用传统Web框架到切换到Spring Boot后的总结 中提到关于 Spring Boot 编译打包,Spring Boot 应用程序不用额外部署到外部容器中,可以直接通过 Maven 命 ...
- Spring Boot 项目瘦身指南,瘦到不可思议!
https://blog.csdn.net/yjgithub/article/details/80475521 目录: 前言 瘦身前的 Jar 包 解决方案 一.前言 SpringBoot 部署起来虽 ...
- Spring Boot 项目瘦身指南,非常实用!
一.前言 Spring Boot部署起来虽然简单,如果服务器部署在公司内网,速度还行,但是如果部署在公网,部署起来实在头疼:编译出来的 Jar 包很大,如果工程引入了许多开源组件(Spring Clo ...
- Spring Boot gradle 打包瘦身减少jar包体积 含demo
Spring Boot 1.5.x 打包 demo项目地址 https://gitee.com/youngboyvip/package-example 解决问题 Spring Boot 项目包太大上传 ...
- spring boot项目精简瘦身打包
1.背景介绍 当网络不是很给力的时候,一个大的jar包传输是费时的,往往存在修改1分钟,传包10分钟的尴尬时刻. 1)正常打包出来的jar 2)解压出来后的包大小98M 3)lib的jar包大小 综上 ...
- springboot瘦身打包
为什么瘦身打包:Spring Boot把整个项目打包成一个可运行的Jar包(即所谓的Fat Jar),导致了这个Jar包很大(通常有40M+).如今迭代发布时常有的事情,每次都上传一个如此庞大的文件, ...
- Maven打包(瘦身打包部署),不包含第三方依赖jar包
方式1 pom 配置 <properties><startClass>com.answer.jaemon.Application</startClass> < ...
- 记一次Spring boot 和Vue的前后端分离的入门培训
记一次Spring boot 和Vue的前后端分离的入门培训 由于公司之前是写C#的,现在要转 Java分布式 + vue,所以进行一次前后端的简单培训. 前端工具和环境: Node.js V10.1 ...
最新文章
- 怎么把两个不同的属性值进行比较_DDD实战与进阶 值对象
- rhel7 http实例2
- LiveVideoStackCon讲师热身分享 ( 二 ) —— 中美互动直播比较
- Hbase 01_初学必知
- 导出排除的表_excel拆分实例:如何快速制作考勤统计分析表
- 一笔画问题(信息学奥赛一本通-T1341)
- 【uTenux实验】写在开始实验之前
- 怎么创建python django项目_创建Django项目图文实例详解
- 【BP神经网络】使用反向传播训练多层神经网络的原则+“常见问题”
- MongoDB命令学习
- OpenCV_(Using GrabCut extract the foreground object) 使用 GrabCut 算法提取前景物体
- 一文掌握基于深度学习的自动驾驶小车开发(Pytorch实现,含完整数据和源码,树莓派+神经计算棒)
- Xcode6与Xcode5之间的细节差别(Precompile Prefix Header)
- 李沐动手学深度学习d2l
- 多台欧姆龙PLC通过智能网关实现HTTP协议对接MES系统
- Microsoft Edge浏览器或者电脑上其他浏览器的主页被篡改后的解决办法。(适用于联想电脑)
- 论文阅读:SCAFFOLD: Stochastic Controlled Averaging for On-Device Federated Learning
- Java入门篇(一)——如何编写一个简单的Java程序
- 输入字符串,输出字符串中出现次数最多的字母及其出现次数。如果有多个字母出现次数一样,则按字符从小到大顺序输出字母及其出现次数。
- 解决 ENVI App Store安装后无法打开的问题
热门文章
- hadoop集群的集中管理
- bzoj 2733 永无岛
- matlab里motor的符号,motor的用法总结大全
- [视频教程] KBEngine mmo手游开发系列(三) - 角色技能与怪物系统
- [10 Jun 2015 ~ 11 Jun 2015] Deep Learning in arxiv
- webpack概念以及配置文件详解
- 自制FOC控制驱动器
- (转)设置Sysctl.conf用以提高Linux的性能(最完整的sysctl.conf优化方案)
- 电磁阀安装和使用事项
- 一键锁屏源代码c语言,Android一键锁屏开发全过程【源码】【附图】