原文地址: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 依赖替换为 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自带的加解密算法实现。原文: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.dirloader.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.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=“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 依赖相关推荐

  1. Spring Boot项目瘦身

    目录 1,什么是瘦身? 2,为什么要瘦身? 3,如何瘦身? 3.1,瘦身思路: 3.2,瘦身方法 4,瘦身后运行 1,什么是瘦身? 瘦身:thinBody,又称"减肥"." ...

  2. Spring Boot 项目瘦身指南,瘦到不可思议!129M->1.3M

    之前在 从使用传统Web框架到切换到Spring Boot后的总结 中提到关于 Spring Boot 编译打包,Spring Boot 应用程序不用额外部署到外部容器中,可以直接通过 Maven 命 ...

  3. Spring Boot 项目瘦身指南,瘦到不可思议!

    https://blog.csdn.net/yjgithub/article/details/80475521 目录: 前言 瘦身前的 Jar 包 解决方案 一.前言 SpringBoot 部署起来虽 ...

  4. Spring Boot 项目瘦身指南,非常实用!

    一.前言 Spring Boot部署起来虽然简单,如果服务器部署在公司内网,速度还行,但是如果部署在公网,部署起来实在头疼:编译出来的 Jar 包很大,如果工程引入了许多开源组件(Spring Clo ...

  5. Spring Boot gradle 打包瘦身减少jar包体积 含demo

    Spring Boot 1.5.x 打包 demo项目地址 https://gitee.com/youngboyvip/package-example 解决问题 Spring Boot 项目包太大上传 ...

  6. spring boot项目精简瘦身打包

    1.背景介绍 当网络不是很给力的时候,一个大的jar包传输是费时的,往往存在修改1分钟,传包10分钟的尴尬时刻. 1)正常打包出来的jar 2)解压出来后的包大小98M 3)lib的jar包大小 综上 ...

  7. springboot瘦身打包

    为什么瘦身打包:Spring Boot把整个项目打包成一个可运行的Jar包(即所谓的Fat Jar),导致了这个Jar包很大(通常有40M+).如今迭代发布时常有的事情,每次都上传一个如此庞大的文件, ...

  8. Maven打包(瘦身打包部署),不包含第三方依赖jar包

    方式1 pom 配置 <properties><startClass>com.answer.jaemon.Application</startClass> < ...

  9. 记一次Spring boot 和Vue的前后端分离的入门培训

    记一次Spring boot 和Vue的前后端分离的入门培训 由于公司之前是写C#的,现在要转 Java分布式 + vue,所以进行一次前后端的简单培训. 前端工具和环境: Node.js V10.1 ...

最新文章

  1. 怎么把两个不同的属性值进行比较_DDD实战与进阶 值对象
  2. rhel7 http实例2
  3. LiveVideoStackCon讲师热身分享 ( 二 ) —— 中美互动直播比较
  4. Hbase 01_初学必知
  5. 导出排除的表_excel拆分实例:如何快速制作考勤统计分析表
  6. 一笔画问题(信息学奥赛一本通-T1341)
  7. 【uTenux实验】写在开始实验之前
  8. 怎么创建python django项目_创建Django项目图文实例详解
  9. 【BP神经网络】使用反向传播训练多层神经网络的原则+“常见问题”
  10. MongoDB命令学习
  11. OpenCV_(Using GrabCut extract the foreground object) 使用 GrabCut 算法提取前景物体
  12. 一文掌握基于深度学习的自动驾驶小车开发(Pytorch实现,含完整数据和源码,树莓派+神经计算棒)
  13. Xcode6与Xcode5之间的细节差别(Precompile Prefix Header)
  14. 李沐动手学深度学习d2l
  15. 多台欧姆龙PLC通过智能网关实现HTTP协议对接MES系统
  16. Microsoft Edge浏览器或者电脑上其他浏览器的主页被篡改后的解决办法。(适用于联想电脑)
  17. 论文阅读:SCAFFOLD: Stochastic Controlled Averaging for On-Device Federated Learning
  18. Java入门篇(一)——如何编写一个简单的Java程序
  19. 输入字符串,输出字符串中出现次数最多的字母及其出现次数。如果有多个字母出现次数一样,则按字符从小到大顺序输出字母及其出现次数。
  20. 解决 ENVI App Store安装后无法打开的问题

热门文章

  1. hadoop集群的集中管理
  2. bzoj 2733 永无岛
  3. matlab里motor的符号,motor的用法总结大全
  4. [视频教程] KBEngine mmo手游开发系列(三) - 角色技能与怪物系统
  5. [10 Jun 2015 ~ 11 Jun 2015] Deep Learning in arxiv
  6. webpack概念以及配置文件详解
  7. 自制FOC控制驱动器
  8. (转)设置Sysctl.conf用以提高Linux的性能(最完整的sysctl.conf优化方案)
  9. 电磁阀安装和使用事项
  10. 一键锁屏源代码c语言,Android一键锁屏开发全过程【源码】【附图】