【效率提升】maven 转 gradle 实战 | 京东云技术团队

一、灵魂三问

1、gradle 是什么?

一个打包工具, 是一个开源构建自动化工具,足够灵活,可以构建几乎任何类型的软件,高性能、可扩展、能洞察等。其中洞察,可以用于分析构建过程中数据,提供分析参考,方便排查问题和不断优化构建性能,以下一次编译分析报告。

2、有什么优势

参考官方文章,针对包含10 子模块的工程,相对 maven 构建速度,大概有 2-3 倍的性能提升,增量编译大概 7 倍的性能提升,参考官方

实测对比:

****gradle 耗时maven 耗时
全新构建(clean 及下载依赖包)1m 35s1m58s
全新构建(clean)43s60s
增量构建14s43s

gradle 执行命令: time gradle clean build package -x test

mvn 执行的命令: time mvn clean package -Dmaven.test.skip=true -f $(pwd) -T 1C -Dmaven.artifact.threads=16

综述,经过多轮测试,在增量编译场景优势比较突出平均有 2 倍的性能提升,工程模块越多效率提升越大。

3、迁移是否容易

摸着心口说,并不容易,虽然官方提供了一键迁移的工具,但是还是有一定学习成本,但改造完成确实节省了大把的时间,尤其是改了一两行代码再次编译时。

二、动动手试试

1、安装 gradle

推荐使用 sdkman ,主要用于工具多版本管理的工具,如 java 、gradle 、maven 等可以根据实际情况安装使用其中某个一个版本,如jdk8,jdk11 等,版本间切换非常简便。 sdk 介绍

sdk install  gradle 8.1.1

2、执行迁移命令

在当前 maven 工程下,执行如下的命令。

gradle init 
Found a Maven build. Generate a Gradle build from this? (default: yes) [yes, no] yes
Select build script DSL:1: Groovy2: Kotlin
Enter selection (default: Groovy) [1..2] 1
Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no] no

不出意外下,会在默认子模块下添加 build.gradle 文件,如下图:

文件解释:

1)buildSrc/main/groovy/com.jd.pegasus.java-conventions.gradle :里面配置的是内网私服库地址。

repositories {mavenLocal()maven {url = uri('http://artifactory.jd.com/libs-releases')allowInsecureProtocol = true}maven {url = uri('http://artifactory.jd.com/libs-snapshots')allowInsecureProtocol = true}maven {url "https://plugins.gradle.org/m2/"}}

2)gradle.properties :配置环境变量,必须设置 jvm 的参数,否则很容易 oom 。 更多配置

# gradle jvm 设置
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# 开启并行编译
org.gradle.parallel=true

3)build.gradle :包含了编译过程中使用的插件,id ‘com.jd.pegasus.java-conventions’ 代表自定义的插件。 dependencies 为工程所使用的依赖。

plugins {id 'com.jd.pegasus.java-conventions'
}dependencies {api project(':pegasus-service')api project(':pegasus-common')implementation 'org.springframework.boot:spring-boot:2.1.9.RELEASE'api project(':component-metric')testImplementation 'org.springframework.boot:spring-boot-starter-test:2.1.9.RELEASE'annotationProcessor 'org.projectlombok:lombok:1.18.10'
}description = 'pegasus-worker'

这里面有一个dependencies 依赖项中 api 与 implementation 区别,参见如下解释:

假设你正在维护一个名为 MyLibrary 的库,它依赖于另一个库 InternalLibrary。你希望 MyLibrary 的用户能够使用 InternalLibrary 中的某些类和方法,但不希望他们使用其他类和方法。在这种情况下,你可以在 MyLibrary 的 build.gradle 文件中使用 api 配置来声明对 InternalLibrary 的依赖: dependencies { api project(‘:InternalLibrary’) } 这样,当其他模块依赖于 MyLibrary 时,它们也能够访问 InternalLibrary 中的类和方法。 但是,如果你不希望 MyLibrary 的用户能够访问 InternalLibrary 中的任何内容,你可以在 MyLibrary 的 build.gradle 文件中使用 implementation 配置来声明对 InternalLibrary 的依赖: dependencies { implementation project(‘:InternalLibrary’) } 这样,当其他模块依赖于 MyLibrary 时,它们将无法访问 InternalLibrary 中的任何内容。

简单点就是如果你想把你依赖组件,让使用你组件人也知道的明明白白的也能使用,那你就用 api 把组件传递下去 ,反之就用 implementation ,就自个偷摸使用了,对第三方隐藏了一些内部细节。

3、gitignore 排除不要的目录和文件

# Gradle generated files
build/
.gradle/
/out/
/.gradle/

4、允许以不安全的方式访问私服库

# 在这个文件里面,buildSrc/main/groovy/com.jd.pegasus.java-conventions.gradle repositories {mavenLocal()maven {url = uri('http://artifactory.jd.com/libs-releases')allowInsecureProtocol = true}
}

5、解决 lombok 引发的编译问题

通过 lombok 注解会在编译过程中把注解的类进行扩展,添加 get 、set 、toString 方法等。

# 在编译出错的模块里面 build.gradle 文件中添加注解处理器,annotationProcessor  如下:
dependencies {api project(':pegasus-service')annotationProcessor 'org.projectlombok:lombok:1.18.10'
}

6、解决版本依赖冲突

版本冲突指同依赖组件出现不同的版本情况,如pegasus-common 模块依赖的 fastjson 有1.2.83-jdsec.rc1, 1.2.29 and 1.2.12 三个版本,gradle 会自动处理仲裁,规则有以下几点:

1)冲突时会默认采用最新的版本。

2)通过 strictly 标记主要用于降级到指定的版本,如传递依赖引入的版本高,当前版本不兼容,那可以通过这个关键字设置指定的版本。

implementation('com.alibaba:fastjson'){   version{       strictly("1.2.12")    } 
}
或者简写为 
implementation 'com.alibaba:fastjson:1.2.29!!!'

3)force 的优先级会比较高,会覆盖 strictly 策略

configurations.all {resolutionStrategy {// 在这里定义您的依赖解析规则//force 'com.alibaba:fastjson:1.2.12'}
}

排查某个模块的依赖冲突

gradle :pegasus-common:dependencyInsight --configuration compileClasspath --dependency com.alibaba:fastjson

7、如何构建 zip 包

以 springboot 为例,参考如下代码即可,在子工程 build.gradle 文件里。

。
plugins {id 'com.jd.pegasus.java-conventions'// 引入springboot 插件id 'org.springframework.boot' version '2.5.6'
}// 指定 jar 启动的入口函数
bootJar {manifest {attributes 'Main-Class': 'com.jd.pegasus.Application'}
}
// 构建 zip 压缩包,包含启动脚本 bin 目录和 配置文件 conf 目录
task packageZip(type: Zip) {archiveFileName = "${project.name}-${project.version}.zip"destinationDirectory = file("${project.buildDir}")from("${project.projectDir}/src/main/bin") {into "bin"}from("${project.buildDir}/resources/main/conf") {into "conf"}from("${project.buildDir}/libs/${project.name}-${project.version}.jar") {into "lib"}// 表示此任务的运行依赖其它 子任务。dependsOn bootJardependsOn build
}

8、执行构建命令

# -x test 排除单测
gradle clean  build package -x test  

三、附录参考

1.一文搞懂Gradle的依赖管理和版本决议

  1. gradle 与 maven 性能对比

  2. 爬坑指南 – 理解 Plugin、Task、构建流程

  3. 如何定位和解决依赖冲突

  4. Gradle依赖之‘五种依赖配置’

  5. Migrating Builds From Apache Maven

后记:

听说 maven 不甘寂寞,由 gradle 和 Takari 的灵感,做了一个守护的 mvnd ,在增量编译场景效率杠杠的,有时间测试对比下。 mvnd 参考

作者:京东科技 宁利广

来源:京东云开发者社区 转载请注明来源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/115531.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一招解除csdn复制限制

先看这个代码 python读取英文pdf翻译成中文pdf文件导出代码 想要复制代码,csdn有限制怎么办(csdn流氓,无耻) 解除方法 ctrlu 看效果

UOS Deepin Linux 安装 anaconda

UOS Deepin Linux 安装 anaconda 下载 anaconda 官网下载 国内开源镜像站下载 官网下载 anaconda 官网: https://www.anaconda.com/ 点击右上角 Free Download 按钮 跳转值下载页面:https://www.anaconda.com/download 国内开源镜像站下载 清华大学开源…

TouchGFX之画布控件

TouchGFX的画布控件,在使用相对较小的存储空间的同时保持高性能,可提供平滑、抗锯齿效果良好的几何图形绘制。 TouchGFX 设计器中可用的画布控件: LineCircleShapeLine Progress圆形进度条 存储空间分配和使用​ 为了生成反锯齿效果良好的…

下载github.com上的依赖资源

下载github.com上的依赖资源(需要反复试才能成功,所以单独安装) export GIT_TRACE1 export GIT_CURL_VERBOSE1 pip install githttps://github.com/PanQiWei/AutoGPTQ.git -i https://pypi.mirrors.ustc.edu.cn/simple --trusted-hostpypi.mi…

stm32之GPIO库函数点灯分析

stm32官方为了方便开发者,利用CubeMX 生成HAL库有关的C代码。HAL库就是硬件抽象层(hardware abstraction layer),生成一系列的函数帮助我们快速生成工程,脱离复杂的寄存器配置。stm32相对于51来功能强大,但是寄存器的数量也不是一…

2023华为杯研究生数学建模C题分析

完整的分析查看文末名片获取! 问题一 在每个评审阶段,作品通常都是随机分发的,每份作品需要多位评委独立评审。为了增加不同评审专家所给成绩之间的可比性,不同专家评审的作品集合之间应有一些交集。但有的交集大了,则…

Openresty(二十二)ngx.balance和balance_by_lua终结篇

一 灰度发布铺垫 ① init_by_lua* init_by_lua init_by_lua_block 特点: 在openresty start、reload、restart时执行,属于master init 阶段机制: nginx master 主进程加载配置文件时,运行全局Lua VM级别上的参数指定的Lua代码场景: …

云流化:XR扩展现实应用发展的一个新方向!

扩展现实的发展已经改变了我们工作、生活和娱乐的方式,而且这才刚刚开始。扩展现实 (Extended reality, XR) 涵盖了沉浸式技术,包括虚拟现实、增强现实和混合现实。从游戏到虚拟制作再到产品设计,XR 使人们能够以前所未有的方式在计算机生成的…

Linux下的Docker安装,以Ubuntu为例

Docker是一种流行的容器化平台,它能够简化应用程序的部署和管理。 Docker安装 1、检查卸载老版本Docker(为保证安装正确,尽量在安装前先进行一次卸载) apt-get remove docker docker-engine docker.io containerd runc 2、Dock…

[JAVAee]SpringBoot日志文件

目录 日志的作用 SpringBoot中的日志 框架说明 日志对象的获取 日志的分类 日志的级别设置 日志的打印 日志的持久化 日志的作用 日志可以帮助我们发现程序的问题并进行定位.日志还可以记录用户的登录信息,分析用户的意图.日志能记录程序执行的时间,记录数据.为日后的程…

杂记 | 使用gitlab-runner将python项目以docker镜像方式流水线部署到服务器(解决部署缓慢和时区不对的问题)

文章目录 01 需求背景1.1 需求1.2 步骤 02 编写BaseDockerfile2.1 编写2.2 说明2.3 执行 03 编写Dockerfile04 编写.gitlab-ci.yml05 项目结构 01 需求背景 1.1 需求 我有一个python项目,该项目可能是一个服务器监控程序,也可能是一个后端程序&#xf…

CSS滚动条详解(::-webkit-scrollbar )

滚动条出现的事件&#xff1a; 当设置定宽或者定高的元素添加overflow:scroll属性&#xff0c;会出现滚动条&#xff0c;但是原生样式的会比较丑影响美观。 <div class"content"><div class"contain"></div> </div>.content {wid…