Gradle使用总结

Posted 流子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gradle使用总结相关的知识,希望对你有一定的参考价值。

下载Gradle地址:Gradle Build Tool

gradle init
使用gradle init即可创建一个gradle项目的骨架

文件说明
可以看到一共创建了2个目录和6个文件,其中2个目录和4个文件都跟wrapper有关:

gradlew:linux或者Unix下用于执行wrapper命令的Shell脚本
gradlew.bat:Windows下用于执行wrapper命令的批处理脚本
gradle-wrapper.jar:用于下载Gradle的相关代码实现
gradle-wrapper.properties:wrapper所使用的配置信息,比如gradle的版本等信息

详细的信息可参看前文的说明:

https://blog.csdn.net/liumiaocn/article/details/84232536
另外就是settings.gradle和build.gradle:

build.gradle: 用于存放构建相关的Task
settings.gradle: 用于存放设定相关的信息
详细的信息可参看前文的说明:
https://blog.csdn.net/liumiaocn/article/details/84192318

内容确认

  • settings.gradle
    通过内容确认可以看到,settings.gradle中只设定了rootProject.name
  • build.gradle
    而build.gradle则没有任何设定,只有注释,这也正是初始化的意义所在。

init & wrapper

init的任务是依赖于wrapper的,执行init的时候同时会执行wrapper,因为wrapper是gradle官方推荐的方式,自然在初始化的时候也会将wrapper集成进去。

API:Overview (Gradle API 6.5)

Overview (Gradle API 7.2)

https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/maven/MavenDeployer.html

打包 

>

jar 包会出现在这里 \\build\\libs

预装个eclipse的插件,方便对build.gradle编译,Minimalist Gradle Editor 1.0.1

指令 

gradle -version 查看版本

------------------------------------------------------------
Gradle 4.4.1
------------------------------------------------------------

Build time:   2017-12-20 15:45:23 UTC
Revision:     10ed9dc355dc39f6307cc98fbd8cea314bdd381c

Groovy:       2.4.12
Ant:          Apache Ant(TM) version 1.9.9 compiled on February 2 2017
JVM:          1.8.0_66 (Oracle Corporation 25.66-b17)
OS:           Windows 10 10.0 amd64

gradle projects 查看工程信息

gradle tasks 查看任务信息

gradle task name 执行task任务

Gradle 工作流程
以multi-project build为例,Gradle工作流程如下:

初始化阶段:首先解析settings.gradle
Configration阶段:解析每个Project中的build.gradle,解析过程中并不会执行各个build.gradle中的task。
经过Configration阶段,Project之间及内部Task之间的关系就确定了。一个 Project 包含很多 Task,每个 Task 之间有依赖关系。Configuration 会建立一个有向图来描述 Task 之间的依赖关系, 所有Project配置完成后,会有一个回调project.afterEvaluate,表示所有的模块都已经配置完了。
执行Task任务

subprojects 和 allprojects 的区别

allprojects是对所有project的配置,包括Root Project。而subprojects是对所有Child Project的配置

Task内部执行顺序

当我们执行Task的时候,就是执行其拥有的actions列表,是一个List。把Task执行之前、Task本身执行、Task之后执行分别称为doFirst、doSelf、doLast

buildscript代码块的作用

其实答案非常简单。buildscript中的声明是gradle脚本自身需要使用的资源。可以声明的资源包括依赖项、第三方插件、maven仓库地址等。

而在build.gradle文件中直接声明的依赖项、仓库地址等信息是项目自身需要的资源。

gradle是由groovy语言编写的,支持groovy语法,可以灵活的使用已有的各种ant插件、基于jvm的类库,

这也是它比maven、 ant等构建脚本强大的原因。虽然gradle支持开箱即用,但是如果你想在脚本中使用一些第三方的插件、类库等,

就需要自己手动添加对这些插件、类库的 引用。而这些插件、类库又不是直接服务于项目的,而是支持其它build脚本的运行。

所以你应当将这部分的引用放置在buildscript代码块中。 gradle在执行脚本时,会优先执行buildscript代码块中的内容,

然后才会执行剩余的build脚本。

Gradle中的buildScript代码块

如何升级?
我们提供了一个文档来帮助你从Gradle 4.x升级到Gradle 5.0。在升级之前,我们建议你:

使用Gradle包装器升级到Gradle 6.5.1:gradle wrapper --gradle-version = 6.5.1

运行gradle help --scan列出已弃用的Gradle API以及使用了这些API的地方(包括插件)。

更新Gradle插件,尤其是构建扫描报告中列出的已启用的插件。
 

如何查看废弃的打印信息

gradle --warning-mode all

dependencies里的依赖变化
当我们升级gradle 时,默认的依赖由之前的compile更改为implementation了。

3.0 以下版本build.gradle中依赖的写法:

compile fileTree(dir: 'libs', include: ['*.jar'])

但在3.0后的写法为

implementation fileTree(dir: 'libs', include: ['*.jar'])


二、区别
在3.X版本中,compile 指令被标注为过时方法,而新增了两个依赖指令,一个是implementation和api,这两个都可以进行依赖添加,但是有什么区别呢?

api
完全等同于compile指令,没区别,你将所有的compile改成api,完全没有错。

implementation
这个指令的特点就是,对于使用了该命令编译的依赖,对该项目有依赖的项目将无法访问到使用该命令编译的依赖中的任何程序,也就是将该依赖隐藏在内部,而不对外部公开。

示例
比如我在一个library中使用implementation依赖了gson库,然后我的主项目依赖了library,那么,我的主项目就无法访问gson库中的方法。这样的好处是编译速度会加快,推荐使用implementation的方式去依赖,如果你需要提供给外部访问,那么就只能使用api方式了。

在Google IO相关话题的中提到了一个建议,就是依赖首先应该设置为implementation的,如果没有错,那就用implementation,如果有错,那么使用api指令,这样会使编译速度增快。

如何生成pom.xml文件和子项目?

gradle install

成功后,会在 build目录下的 poms 文件夹下生成 pom-default.xml,将其改名为 pom.xml 拷贝到项目的根目录下即可。

打包

gradle jar

发布全部项目

 gradle publish  

发布单独一个子项目

gradle gamioo-game:publish 

发布的仓库除了nexus,还可以选择github自身的,具体请参考

GitHub Packages in Action

签名:

2.gpg秘钥安装

2.1 安装gpg

gpg(GunPG)是一款用于生成秘钥的加密软件。

Windows下载地址:

GnuPG - Download​www.gnupg.org

Ubuntu可以使用如下命令进行安装:

yum install gnupg

gpg 常用的命令

  • gpg --version 检查安装成功没
  • gpg --gen-key 生成密钥对
  • gpg --list-keys 查看公钥
  • gpg --keyserver hkp://keyserver.ubuntu.com:11371 --send-keys 公钥ID 将公钥发布到 PGP 密钥服务器
gpg --keyserver http://keys.gnupg.net:11371/ --send-keys 538475122768AFFBC42CE22863F8B684DBACA97A
  • gpg --keyserver hkp://keyserver.ubuntu.com:11371 --recv-keys 公钥ID 查询公钥是否发布成功
gpg --keyserver hkp://keyserver.ubuntu.com:11371 --recv-keys 538475122768AFFBC42CE22863F8B684DBACA97A

2.2 创建秘钥并发布

运行命令gpg --gen-key 生成密钥对,按照提示输入真实姓名,邮箱等。然后生成秘钥时候,会让你输入两次密码,这个密码要记住。后续会用到。

完成后运行命令gpg --list-keys ,查看本地秘钥

PS E:\\stone\\happy\\server\\trunk\\gamioo> gpg --list-keys
C:/Users/Allen Jiang/AppData/Roaming/gnupg/pubring.kbx
------------------------------------------------------
pub   rsa2048 2020-07-24 [SC]
      538475122768AFFBC42CE22863F8B684DBACA97A
uid           [ultimate] gamioo <41157128@qq.com>
sub   rsa2048 2020-07-24 [E] [expires: 2022-07-24]

导出绝密密钥时要把后缀改成gpg

注意,要把sonatype的账号密码,密钥密码等相关信息放到独立的地方,以免被共享出去,一般默认我们会在 $USER_HOME/.gradle 该目录下创建gradle.properties文件,比如我的就是C:\\Users\\Allen Jiang\\.gradle下

内容如下:

NEXUS_USERNAME=你的NEXUS账号
NEXUS_PASSWORD=你的NEXUS密码

signing.keyId=8位的秘钥指纹
signing.password=gpg文件的密码
signing.secretKeyRingFile=E:/ooxx.gpg gpg文件路径

发布到maven中央库,需要在staging repository先close在release

先在 Nexus Repository Manager进行close,release等操作(注意这里会检测)
然后在issue中回复服务人员,提出同步到中央库 (半天左右)。

要查看编译时的日志,可以做一下指令

 gradle build --info  

每次发布正式版,都需要去做close和release的操作

默认新建一个gradle项目,并不会新建java,resource文件夹,需要自己手工来写,那么,可否由脚本创建呢?答案是可以。

创建task

		/**创建java和resource目录*/
task createDirs 
	sourceSets*.java.srcDirs*.each  it.mkdirs() 
	sourceSets*.resources.srcDirs*.each  it.mkdirs() 

执行 gradle createDirs ,就创建好了

如何进行一次编译并能看到日志

gradle  -b build.gradle release -x test --info --stacktrace

如何打印临时日志

logger.info("allen " + 'git rev-parse --short HEAD'.execute().text.trim());

读取环境变量

 logger.info( System.getenv("PATH"));

用jenkins 调用gradle ,然后通过gradle调用git会导致版本号取不到的问题

用以下方式获取,关键是

[], project.rootDir 这个
manifest.attributes["Implementation-Version"] = project.version + "-" + 'git rev-parse --short HEAD'.execute([], project.rootDir).text.trim() + "[" + 'git rev-list HEAD --count'.execute([], project.rootDir).text.trim() + "]-S" + new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+08:00")) + "R1";

用CI工具蓝盾/jekins 在gradle打包编译时,会遇到编译失败,日志会有如下异常:

 ----- End of the daemon log -----
 FAILURE: Build failed with an exception.
 * What went wrong:
 Gradle build daemon disappeared unexpectedly (it may have been killed or may have crashed)
 
 * Try:
 Run with --debug option to get more log output. Run with --scan to get full insights.
 
 * Exception is:
 org.gradle.launcher.daemon.client.DaemonDisappearedException: Gradle build daemon disappeared unexpectedly (it may have been killed or may have crashed)
 	at org.gradle.launcher.daemon.client.DaemonClient.handleDaemonDisappearance(DaemonClient.java:249)
 	at org.gradle.launcher.daemon.client.DaemonClient.monitorBuild(DaemonClient.java:222)
 	at org.gradle.launcher.daemon.client.DaemonClient.executeBuild(DaemonClient.java:184)
 	at org.gradle.launcher.daemon.client.DaemonClient.execute(DaemonClient.java:147)
 	at org.gradle.launcher.daemon.client.DaemonClient.execute(DaemonClient.java:98)
 	at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:57)
 	at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:212)
 	at org.gradle.launcher.cli.DefaultCommandLineActionFactory$ParseAndBuildAction.execute(DefaultCommandLineActionFactory.java:275)
 	at org.gradle.launcher.cli.DefaultCommandLineActionFactory$ParseAndBuildAction.execute(DefaultCommandLineActionFactory.java:247)
 	at org.gradle.launcher.cli.DebugLoggerWarningAction.execute(DebugLoggerWarningAction.java:82)
 	at org.gradle.launcher.cli.DebugLoggerWarningAction.execute(DebugLoggerWarningAction.java:30)
 	at org.gradle.launcher.cli.WelcomeMessageAction.execute(WelcomeMessageAction.java:92)
 	at org.gradle.launcher.cli.WelcomeMessageAction.execute(WelcomeMessageAction.java:38)
 	at org.gradle.launcher.cli.NativeServicesInitializingAction.execute(NativeServicesInitializingAction.java:44)
 	at org.gradle.launcher.cli.NativeServicesInitializingAction.execute(NativeServicesInitializingAction.java:26)
 	at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:41)
 	at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:26)
 	at org.gradle.launcher.cli.DefaultCommandLineActionFactory$WithLogging.execute(DefaultCommandLineActionFactory.java:240)
 	at org.gradle.launcher.Main.doAction(Main.java:35)
 	at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:50)
 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:67)
 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 	at java.lang.reflect.Method.invoke(Method.java:498)
 	at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:60)
 	at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:37)
 	at org.gradle.launcher.GradleMain.main(GradleMain.java:31)
 * Get more help at https://help.gradle.org

是因为CI工具并发执行会将gradle杀掉,

只要在gradle指令后追加 --no-daemon 就行

开发环境开启 gradle daemon 可以极大的提高编译速度

touch ~/.gradle/gradle.properties && echo "org.gradle.daemon=true" >> ~/.gradle/gradle.properties

The Gradle Daemon

正式打包环境和 Continuous Integration 环境不建议开启 daemon。
打 release 包时可通过 --no-daemon 命令暂时关闭 daemon。

也可以通过调整gradle运行时的内存处理此问题,毕竟3.0后,默认开始这个配置的,

在项目的根目录下建立gradle.properties,里面加

org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.parallel=true

然后在执行gradle命令时,加上

gradle  -Dorg.gradle.jvmargs="-Xmx2048m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" release -x test --info --stacktrace

也可以把gradle.properties放到gradle根目录下/home/cnc_build/svr_pkg/gradle-6.8.3

如何在gradle test 时也能把异常信息输出到 gradle r日志中

如何调用?

gradle   :gamioo-game:test --tests io.gamioo.game.ResourceManagerTest

build.gradle 里如何设置

    test 
        useJUnitPlatform();
        testLogging 
            showStandardStreams true;
        
    

并且要让异常控制台打印输出,像这种方式,log4j2配置没法起效果,

try
...
...
  catch (Exception e) 
            e.printStackTrace();
            throw e;
        

这个感觉还可以改进,不知网友们有什么好的办法?

编译的时候,有时候会遇到以下的告警:

警告: HotspotThreadMBean是内部专用 API, 可能会在未来发行版中删除
import sun.management.HotspotThreadMBean

如果想要屏蔽,只要在build.gradle里添加

    compileJava 
        options.compilerArgs << '-XDignore.symbol.file'
        options.fork = true
        options.forkOptions.executable = 'javac'
    

遇到如下异常:

Cannot change dependencies of dependency configuration ':implementation' after it has been included in dependency resolution.

可能你把jar节点放在了repositories 和dependencies之间,试着把jar节点移动到dependencies下面

如何将maven项目改造成gradle项目

Gradle官方非常贴心的内置了插件,可以一键将Maven POM转换为Gradle配置。只需要在项目目录内执行:

gradle init

然后,按照提示,将该Maven项目转换为一个Gradle项目即可。Gradle会自动为我们生成根项目的build.gradle、settings.gradle和gradle wrapper文件夹,当然,还有每个子项目的build.gradle文件(太强大了,笔芯Gradle♥️)

然鹅,光是这样当然是不够的,自动生成的Gradle配置是无法通过编译的...我们还需要继续按照原有的编译配置继续调整Gradle配置文件。

---------------------------------

如何在命令行运行gradle指定 JDK 版本?

可以在项目的根目录下创建文件 gradle.properties,里面设置JDK目录:

org.gradle.java.home=D:\\\\Program Files\\\\Java\\\\TencentKona-11.0.16.b2

以上是关于Gradle使用总结的主要内容,如果未能解决你的问题,请参考以下文章

怎样使用Android Studio引用本地aar文件

iOS App Extension 看不到主项目的类

在引用的项目中获取主项目的版本

导入gradle项目

项目中Gradle使用总结

gradle学习总结