2024-11-14

Gradle - Zero to One [8.6]

 
Problems you may encounter:
  1. Gradle version is incompatible with SpringBoot
  1. The Gradle version is incompatible with the idea version
Build Tools
Advantage
Disadvantage
Ant
Flexible to use and faster than Maven and gradle
Without imposing any coding convention on the project directory structure, developers need to write complex XML file build instructions, which is a challenge for developers.
Maven
Follow a set of project directory structures with conventions greater than configuration, use agreed GAV coordinates for dependency management, and focus on package management.
The project construction process is rigid, configuration file writing is not flexible enough, it is inconvenient to customize components, and the construction speed is slower than Gradle
Gradle
It combines the flexibility of Ant scripts + the advantages of Maven conventions over configured project directories, supports a variety of remote warehouses and plug-ins, and focuses on the construction of large projects.
The learning cost is high, there is little information, the script is flexible, and the version compatibility is poor.

1. Install Gradle

Windows
First go to the C:\Program Files\JetBrains\IntelliJ IDEA 2023.3.3\plugins\gradle\lib directory to confirm the gradle version compatible with the current Idea. At least version 8.4 of gradle must be installed here.
notion image
  1. URL: https://gradle.org/releases/ →Select the corresponding binary version to download. The bin directory of the complete version may not have a startup command.
  1. Configure environment variables My Computer → Properties → Advanced System Settings → Environment Variables
    1. notion image
      notion image
    C:\Users\ArtistS>gradle -v Welcome to Gradle 8.6! Here are the highlights of this release: - Configurable encryption key for configuration cache - Build init improvements - Build authoring improvements For more details see https://docs.gradle.org/8.6/release-notes.html ------------------------------------------------------------ Gradle 8.6 ------------------------------------------------------------ Build time: 2024-02-02 16:47:16 UTC Revision: d55c486870a0dc6f6278f53d21381396d0741c6e Kotlin: 1.9.20 Groovy: 3.0.17 Ant: Apache Ant(TM) version 1.10.13 compiled on January 4 2023 JVM: 17.0.10 (Oracle Corporation 17.0.10+11-LTS-240) OS: Windows 11 10.0 amd64
    1. Configure the gradle local warehouse, My Computer → Properties → Advanced System Settings → Environment Variables, add the following configuration
      1. notion image
    MacOS
    1. Go to the following URL and download the complete version of V8.6 https://gradle.org/releases/
    1. Move it to your folder rather than put it in the Download.
    1. vim ~/.bash.profile and add the following configruation
      1. export GRADLE_HOME=/Users/artists/Software/gradle-8.7 export PATH=${PATH}:${GROOVY_HOME}/bin:${GRADLE_HOME}/bin
    1. source .bash_profile
    1. gradle -v
      1. artists@Artists-MacBook-Pro ~ % gradle -v Welcome to Gradle 8.7! Here are the highlights of this release: - Compiling and testing with Java 22 - Cacheable Groovy script compilation - New methods in lazy collection properties For more details see https://docs.gradle.org/8.7/release-notes.html

    2. Gradle project directory structure

    The default directory structure of the Gradle project is consistent with that of the Maven project, both based on Convention Over Configuration. The complete project directory structure is as follows:
    notion image
    Gradle Directory
    Maven Directory
    build → Encapsulates compiled bytecode, packaged [Jar, War], test report and other information
    target → The compiled classes files will be stored inside.
    src → To put source code
    src → To put source code
    settings.gradle → Settings file, defines project and sub-project name information, and has a one-to-one correspondence with the project
    build.gradle → Build script, each Project (can be understood as a maven module) has a build.gradle
    pom.xml → Build script, store dependencies
    Tip: gradlew.bat and gradlew execute the gradle instructions in the wrapper version specified in gradle, not the locally installed gradle instructions. So if you only compile locally, there is no need for these three folders to exist.
     

    3. Create Gradle Project

    3.1 Use spring initializr to create project

    1. Open https://start.spring.io/
    1. Fill in the project details
      1. notion image
    1. Drag the automatically downloaded file to the Git repository and decompress it.
      1.  

    3.2 Use Gradle Command to create project

    1. Create a folder named gradle02 , input command gradle init by cmd
      1. notion image
    1. Select as needed to complete creation.
     

    4. Gradle Command

    Gradle command must execute under a directory with build.gradle
    notion image
    Explanation
    Stage Name
    Description
    check
    Check the quality of code
    test
    Test and generate test report
    testClasses
    Integrate the src/test directory
    compileTestJava
    Compile src/test/java
    processTestResources
    Compile src/test/resources
    compileJava
    Compile src/main/java
    processResources
    Compile src/main/resources
    jar
    Make it into a jar package
    war
    Make it into a war package
    tar
    Make it into a tar package
    zip
    Make it into a zip package
    startScripts
    Generate startup script
     
    Command
    Description
    Example
    gradle build
    Build the project including compile, test, package, and so on
    gradle build -x test
    Build without test
    gradle classes
    Compile business code and configuration file
    gradle clean
    Clear the build directory, it won’t clear the sub-project’s build directory
    gradle dependencies
    List all dependencies as a dependency tree
    gradle help --task [Task Name]
    Display details of specific task
    gradle init
    Init Gradle project
    gradle init --type pom Convert Maven project to a Gradle Project.
    gradle properties
    List properties list of current project
    gradle run
    Run a service, need support for application plugin, and specific main startup class.
    gradle tasks
    List tasks of current project which tasks have been assigned to the task group (Not include parent project and sub project)
    gradle tasks -all
    List all tasks of current project
    gradle tasks --group="[Group Name]"
    List all tasks of specific group
    gradle test
    Compile test code and generate test report
    gradle projects
    List all projects and sub projects and display in hierarchical structure
    gradle wrapper
    Generate wrapper folder
    gradle wrapper --gradle-version= [new gradle version]
    Upgrade the Gradle Wrapper version
    gradle wrapper --gradle-version=8.6
    gradle wrapper --gradle-version [Gradle Version] --distribution-type all
    Associated source code
    gradle wrapper --gradle-version 8.6 --distribution-type all
    gradle -i [task name] gradle [task name]
    Run specific task and print the log which log level over INFO.
    If the task name is camel case, e.g. myTask. If you want to test, you can use both gradle myTask and gradle mT
    -h, --help
    View help information
    -v, --version
    View version details
    -S, --full-stacktrace
    Print all stack trace information (Detailed)
    -s, --stacktrace
    Print user stack trace information
    -q, --quiet
    Log errors only.
    -w, --warn
    Set log level to warn.
    -i, --info
    Set log level to info.
    -d, --debug
    Log in debug mode (includes normal stacktrace).
    -P,--project-prop
    Sets a project property of the root project
    -Pmyprop=myvalue
    -x,--exclude-task
    Exclude a task from being executed
    gradle -x test clean build
    --console=(auto,plain,rich,verbose)
    Specifies which type of console output to generate.
    --rerun-tasks
    Execute all tasks ignoring up-to-date checks
    --rerun-tasks gradle build --rerun-tasks
    --continue
    Force Gradle to execute every task when a failure occurs:
    gradle test --continue`
    The following configuration should be put into gradle.properties, you can also use them in the command.
    Configuration
    Description
    -Dorg.gradle.daemon.debug=true
    Debugging gradle daemon
    -Dorg.gradle.debug
    Debugging gradle client
    -Dorg.gradle.debug.port=[Port Number]
    Specify listening port (Default: 5005)
    -Dorg.gradle.daemon.idletimeout=(number of milliseconds)
    Gradle Daemon will stop itself after this number of milliseconds of idle time. Default is 10800000 (3 hours).
    -Dorg.gradle.logging.level=(quiet,warn,lifecycle,info,debug)
    Set logging level via Gradle properties.
    -Dorg.gradle.console=(auto,plain,rich,verbose)
    Specify console mode via Gradle properties. Different modes are described immediately below.
    --build-cache,--no-build-cache
    Try to reuse output from previous version. The default is off.
    --max-workers
    Set usable workers of Gradle. The default is the number of processors.
    --parallel, --no-parallel
    Parallel execute project. The default is off.
    --daemon,--no-daemon
    Use daemon to build. The default is on.
    --foreground
    Start Gradle daemon in the foreground process.

    5. init.d Folder

    5.1 init.d folder

    We can create xxx.gradle file in C:\Software\gradle-8.6-bin\gradle-8.6\init.d, xxx.gradle file can be executed before build, so you can config some preload operations.

    5.2 Create init.gradle in init.d

    // all projects will use the following configuration allprojects{ /* Dependencies require for the project will download from the following repositories */ repositories{ /* It will try to find the dependencies in maven local repository, this need M2_HOME environment variable */ mavenLocal() // Third-party repository maven { name "Alibaba" ; url"https://maven.aliyun.com/repository/public"} // Third-party repository maven { name "Bstek" ; url"https://nexus.bsdn.org/content/groups/public"} } /* Use for build.gradle build script(e.g. plugins), if these scripts need some dependencies, it will download from the following repositories. */ buildscript{ maven { name "Alibaba" ; url"https://maven.aliyun.com/repository/public"} maven { name "Bstek" ; url"https://nexus.bsdn.org/content/groups/public"} maven { name "M2" ; url'https://plugins.gradle.org/m2/'} } }

    5.3 How to enable init.gradle?

    If there are more than 2 of the following methods, gradle will follow the order to execute them. If there are more than 2 init script under same folder, gradle will execute them in the order of a-z. Each init script will has a gradle instance, the methods and properties you called in the init script, will delegate to this gradle instance.
    1. Use command line
      1. # You can enter this command multiple times to specify multiple files gradle --init-script [DIR_PATH]/init.gradle -q [TASK_NAME]
     
    1. Put init.gradle file into [USER_HOME]/.gradle/ e.g. C:\Users\ArtistS\.gradle
    1. Put xxx.gradle into [USER_HOME]/.gradle/init.d/
    1. Put xxx.gradle into [GRADLE_HOME]/init.d/ e.g. C:\Software\gradle-8.6-bin\gradle-8.6\init.d

    5.4 Repository instructions

    mavenLocal() → Gradle will find the repository by the repository path in maven settings.xml. The order in which gradle searches for jar packages is as follows: [USER_HOME]/.m2/settings.xml[M2_HOME]/conf/settings.xml[USER_HOME]/.m2/repository
    maven{[URL address]} → e.g. private repository, alibaba repository
    mavenCentral() → Maven central repository, no need to config, you can use it by directly declaring it
     
    Gradle can avoid downloading from the remote repository every time by combining the specified repository and remote repository. But here is a problem, if the local maven repository has this dependency, gradle will load it directly. But if the local maven doesn’t have this dependency, Gradle will download it from a remote repository. Keep in mind, that this jar download from the remote repository will not be stored in the maven repository, it will be put into the cache directory, the default path is [USER_HOME]/.gradle/cashes. If you didn’t configure the GRADLE_USER_HOME environment variable. It will be put into [GRADLE_USER_HOME]/cashes. There is no other way to put the downloaded jar into Maven repository, because the format of the jar downloaded in cashes folder is different from the jar stored in the maven repository.
     

    6. Gradle Wrapper

    Gradle Wrapper is a layer of packaging for gradle, it used to solve the problem different projects need different Gradle version. In fact, after having gradle wrapper, we don’t need to configure the Gradle anymore, we can use the gradle project’s wrapper to operate it.
    E.g. I want to share my code to you, there will be 2 scenarios happen
    1. There is no Gradle on your computer.
    1. Your computer has Gradle, but the version too old.
     

    6.1 How to use Gradle wrapper?

    gradelw, gradlew.cmd uses the version specified by gradle wrapper. Because, we will use local Gradle in most cases, so the local Gradle command may be different from Gradle Wrapper command.
    # You can compare the result of these 2 command in your project gradle -v gradlew -v gradlew.bat -v
    But the usage of gradle and gradlew is the same.

    6.2 How to change gradle wrapper version?

    We can use some parameters to control the generation of Wrapper.
    # You can check the gradle wrapper version in gradle-wrapper.properties # You can use this way to upgrade the gradle wrapper (only change the version in # gradle-wrapper.properties but it doesn't download yet.) gradle wrapper --gradle-version=[version number] gradle wrapper --gradle-verison=7.4.2
    The above operation can only change the version in gradle-wrapper.properties. When gradle download the new version?
    Gradle Wrapper Implementation Process:
    1. When we first execute ./gradlew build , gradlew will read gradle-wrapper.properties
    1. Gradle will download the specific version and put it into [GRADLE_HOME]/wrapper/dists
    1. Build local cash, put it into [GRADLE_HOME]/cashes. If the version you want to download already in this folder, you don’t need to download it anymore.
    1. After that, all ./gradlew will use this specific Gradle version.
    notion image

    6.3 gradle-wrapper.properties

    Field
    Description
    distributionBase
    The storage directory after decompression of the gradle compression package
    distributionPath
    The path of gradle compression package, after decompression of the gradle compression package.
    zipStoreBase
    Same as distributionBase, but this is for zip package.
    zipStiorePath
    Same as distributionPath, but this is for zip package.
    distributionUrl
    Download address of gradle distribution compressed package

    6.4 When we use gradle, when we use gradlew

    If the project you wrote before or this project you copy or share from someone, you should use gradlew. But if you create a new project with Gradle, you should use gradle rather than gradlew.

    7. Create & Deploy Project in IDEA

    7.1 Create general JAVA project with Gradle by IDEA

    1. New Project → Update details as the following screenshot
      1. notion image
    1. After create project, the project will use IDEA gradle version, not your local gradle version. If you want to change gradle to your local gradle, File → Settings → Build,Execution,Deployment → Build Tools → Gradle
      1. notion image
    Tip: 1. You can only use this way to change Gradle to your local Gradle when you create a new project. 2. When you add dependencies on gradle.build, these dependencies will download to [GRADLE_USER_HOME]/cashes/module-2/files-2.1
     

    7.2 Create SSM project with Gradle by IDEA

    1. Same step with 7.1
      1. notion image
    1. Open build.gradle and then add war plugin
      1. notion image
    1. Add related dependencies into build.gradle
      1. dependencies { // Spring dependencies implementation 'org.springframework:spring-beans:4.1.7.RELEASE' implementation 'org.springframework:spring-web:4.1.7.RELEASE' implementation 'org.springframework:spring-webmvc:4.1.7.RELEASE' implementation 'org.springframework:spring-tx:4.1.7.RELEASE' implementation 'org.springframework:spring-test:4.0.5.RELEASE' implementation 'org.springframework:spring-jdbc:4.1.7.RELEASE' // Mybatis implementation 'org.mybatis:mybatis-spring:1.2.3' implementation 'org.mybatis:mybatis:3.3.0' // Mysql implementation 'mysql:mysql-connector-java:5.1.36' implementation 'com.alibaba:druid:1.0.15' // jackson implementation 'com.fasterxml.jackson.core:jackson-databind:2.2.3' implementation 'com.fasterxml.jackson.core:jackson-annotations:2.2.3' implementation 'com.fasterxml.jackson.core:jackson-core:2.2.3' // Others implementation 'org.aspectj:aspectjweaver:1.8.6' implementation 'log4j:log4j:1.2.17' implementation 'org.slf4j:slf4j-api:1.7.25' implementation 'jstl:jstl:1.2' compileOnly 'javax.servlet:servlet-api:2.5' testImplementation group: 'junit', name: 'junit', version: '4.12' }
    1. Delete default test folder named java
      1. notion image
    1. Due to this is a web project, we need to create a webapp folder under main folder
      1. notion image
    1. Create WEB-INF folder and add web.xml
      1. <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <context-param> <!--Path and file name of spring configuration file--> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!--Spring listener--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--Config front-end controller--> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- post garbled characters --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--Config convert POST request to PUT or DELETE request--> <filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
    1. Create springmvc.xml under resources folder
      1. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 1.Scan packages --> <context:component-scan base-package="com.artists" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/> </context:component-scan> <!-- 2.Configure internal view resolver--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/"/> <property name="suffix" value=".jsp"/> </bean> <!--3.Handle static resources --> <mvc:default-servlet-handler/> <mvc:annotation-driven/> </beans>
    1. Create package com.artists
    1. Configure mybatis-config.xml
      1. <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> </configuration>
    1. Configure jdbc.properties
      1. jdbc.jdbcUrl=jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true jdbc.driverClass=com.mysql.jdbc.Driver jdbc.userName=root jdbc.password=123456
    1. Configure applicationContext.xml
      1. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 0.Scan packages --> <context:component-scan base-package="com.artists"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/> </context:component-scan> <!-- 1.Load properties file--> <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder> <!-- 2.Configura data source --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="username" value="${jdbc.userName}"></property> <property name="password" value="${jdbc.password}"></property> <property name="url" value="${jdbc.jdbcUrl}"></property> <property name="driverClassName" value="${jdbc.driverClass}"></property> </bean> <!-- 4.Configura transaction --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven> <!-- 1.Configure spring to integrate mybatis --> <bean class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:mybatis-config.xml"></property> </bean> <!-- 2.Configure bean objects for scanning mapper interfaces --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.artists.dao"/> </bean> </beans>
    11. Create related mapper file
    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.artists.dao.AdminMapper"> <select id="getAdminList" resultType="com.artists.bean.Admin"> select id,username,email from admin </select> </mapper>

    7.3 Deploy project with Gretty (not friendly after Gradle 6.x)

    1. Import Gretty plugin
      1. plugins { id 'java' id 'war' id 'org.gretty' version '2.2.0' }
    1. Configure Gretty
      1. gretty{ httpPort=8888 httpsPort=4431 contextPath="/web" debugPort=5005 debugSuspend=true httpsEnabled=true managedClassReload=true //servletContainer='tomcats' //Default container is Jetty }
    1. gradle appRun

    8. Gradle test

    Gradle support JUnit and TestNG, after all test Gradle will generate a test report.
    notion image

    8.1 Junit

    Junit 4.x
    dependencies{ testImplementation group:'junit', name:'junit', version:'4.12' } test{ useJUnit() }
    Junit 5.x
    dependencies{ testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' } test{ useJUnitPlatform() }
    Tip: No matter Junit 4.x or Junit 5.x, we only need to run gradle test under build.gradle, and Gradle will help use to run all the test with @Test, and generate test report.
    // If you don't want to run test you can run the following command gradle build -x // Or you can configure in the gradle.build file test{ enabled(false) useJUnitPlatform() // Support for Junit5 } // If you only want to execute the test under a specific package test{ enabled(true) useJUnitPlatform() // Support for Junit5 include('com/artists/**') // It will only run the test under com.artists package } // If you don't want to execute the test under a specific package test{ enabled(true) useJUnitPlatform() // Support for Junit5 exclude('com/artists/**') // It will only run the test exclude the test under com.artists package }
     

    9. Gradle Life Cycle

    3 stages of Gradle projects:
    Initialization
    - Detects the settings.gradle(.kts) file. - Creat a Settings instance. - Evaluates the settings file to determine which projects (and included builds) make up the build. - Creates a Project instance for every project.
    Configuration
    - Evaluates the build scripts, build.gradle(.kts), of every project participating in the build. - Creates a task graph for requested tasks.
    Execution
    - Schedules and executes the selected tasks. - Dependencies between tasks determine execution order. - Execution of tasks can occur in parallel.
    notion image
    1. Start from [GRADEL_USER_HOME]/init.gradle(init script)
    1. Find settings.gradle, this will record project name, sub project name. Use this project name to find each project.
    1. To execute each build.gradle in each project.(The priority is the build.gradle in parent project will be executed first, and then the sub project will be executed)
    1. During the Configuration stage, it will load all Build Script of all module. The “load” means all statements in build.gradle. Gradle will create corresponding tasks based on the code, and generate DAF consisting of Task.

    10. settings.gradle

    A project is composed of one or more subprojects (sometimes called modules).
    Gradle reads the settings.gradle(.kts) file to figure out which subprojects comprise a project build. Each project can only have 1 settings.gradle.
    Example:
    1. Create a new project named gradle-root
      1. notion image
    1. Create 2 subprojects
      1. notion image
    1. Check the settings.gradle, it will looks like
      1. rootProject.name = 'gradle-root' include 'sub-project01' include 'sub-project02' include 'sub-project03' /** * The configuration can also be * include(':sub-project01') * : -> separator, like / in the path e.g. /root/sub-project01 * '[relative-path]' -> base on the root project * * If you create a sub project of a sub project, the * configuration should like * include 'sub-project01:sub-sub-project01' */
     

    11. Task

    A task represents some independent unit of work that a build performs, such as compiling classes, creating a JAR, generating Javadoc, or publishing archives to a repository.
    notion image
    All available tasks in your project come from Gradle plugins and build scripts. You can list all the available tasks in the project by running the following command in the terminal: gradlew tasks
    Here is a sample task @ArtistS created
    task("task_1", { //This will run during the task configuration section println("This is a simple task.") // The following will run during the task execution section doFirst { println("task_1 doFirst()") } doLast { println("task_2 doLast()") } }) // We can simplified the above code, if you don’t understand anything, you can check // the groovy documentation. task task_1 { //This will run during the task configuration section println "This is a simple task." // The following will run during the task execution section doFirst { println "task_1 doFirst()" } doLast { println "task_2 doLast()" } }
    And go to the root path of gradle-root which is C:\GitRepository\Daydayup\Gradle\gradle-root, and then run gradle -i task_1 . The log is following, you can see when it prints the red context. (If you can’t understand, back to the life cycle section)
    PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle -i task_1 Initialized native services in: C:\GradleRepository\native Initialized jansi services in: C:\GradleRepository\native Received JVM installation metadata from 'C:\Software\jdk17': {JAVA_HOME=C:\Software\jdk17, JAVA_VERSION=17. 0.10, JAVA_VENDOR=Oracle Corporation, RUNTIME_NAME=Java(TM) SE Runtime Environment, RUNTIME_VERSION=17.0.10 +11-LTS-240, VM_NAME=Java HotSpot(TM) 64-Bit Server VM, VM_VERSION=17.0.10+11-LTS-240, VM_VENDOR=Oracle Corporation, OS_ARCH=amd64} Removing 1 daemon stop events from registry Starting a Gradle Daemon (subsequent builds will be faster) Starting process 'Gradle build daemon'. Working directory: C:\GradleRepository\daemon\8.6 Command: C:\Softw are\jdk17\bin\java.exe --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNA MED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED - -add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=ja va.base/java.util.concurrent.atomic=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError - Xms256m -Xmx512m -Dfile.encoding=GBK -Duser.country=CN -Duser.language=zh -Duser.variant -cp C:\Software\gr adle-8.6-bin\gradle-8.6\lib\gradle-launcher-8.6.jar -javaagent:C:\Software\gradle-8.6-bin\gradle-8.6\lib\agents\gradle-instrumentation-agent-8.6.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.6 Successfully started process 'Gradle build daemon' An attempt to start the daemon took 1.201 secs. The client will now receive all logging from the daemon (pid: 53944). The daemon log file: C:\GradleRepository\daemon\8.6\daemon-53944.out.log Starting build in new daemon [memory: 512 MiB] Using 24 worker leases. Received JVM installation metadata from 'C:\Software\jdk17': {JAVA_HOME=C:\Software\jdk17, JAVA_VERSION=17.0.10, JAVA_VENDOR=Oracle Corporation, RUNTIME_NAME=Java(TM) SE Runtime Environment, RUNTIME_VERSION=17.0.10 +11-LTS-240, VM_NAME=Java HotSpot(TM) 64-Bit Server VM, VM_VERSION=17.0.10+11-LTS-240, VM_VENDOR=Oracle Corporation, OS_ARCH=amd64} Watching the file system is configured to be enabled if available Now considering [C:\GitRepository\Daydayup\Gradle\gradle-root] as hierarchies to watch File system watching is active Starting Build Compiling settings file 'C:\GitRepository\Daydayup\Gradle\gradle-root\settings.gradle' using SubsetScriptTransformer. Compiling settings file 'C:\GitRepository\Daydayup\Gradle\gradle-root\settings.gradle' using BuildScriptTransformer. Settings evaluated using settings file 'C:\GitRepository\Daydayup\Gradle\gradle-root\settings.gradle'. Projects loaded. Root project using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle' Included projects: [root project 'gradle-root', project ':sub-project01', project ':sub-project02', project ':sub-project03'] > Configure project : Evaluating root project 'gradle-root' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle'. Compiling build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle' using SubsetScriptTransformer. Compiling build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle' using BuildScriptTransformer. This is a simple task. > Configure project :sub-project01 Evaluating project ':sub-project01' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project01\build.gradle'. Compiling build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project01\build.gradle' using SubsetScriptTransformer. Compiling build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project01\build.gradle' using BuildScriptTransformer. > Configure project :sub-project02 Evaluating project ':sub-project02' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project02\build.gradle'. > Configure project :sub-project03 Evaluating project ':sub-project03' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project03\build.gradle'. All projects evaluated. Task name matched 'task_1' Selected primary task 'task_1' from project : Tasks to be executed: [task ':task_1'] Tasks that were excluded: [] Resolve mutations for :task_1 (Thread[Execution worker Thread 2,5,main]) started. :task_1 (Thread[included builds,5,main]) started. > Task :task_1 Caching disabled for task ':task_1' because: Build cache is disabled Task ':task_1' is not up-to-date because: Task has not declared any outputs despite executing actions. task_1 doFirst() task_1 doLast() BUILD SUCCESSFUL in 4s 1 actionable task: 1 executed Watched directory hierarchies: []

    11.1 Task Behavior

    This section talks about action execution order. Totally speaking, there is an action list, doFirst() will be put at the start of this action list, and doLast() will be put at the end of this action list. Between these 2 task behaviors is self-action. You may saw some code like
    task << { println("<< means doLast() only can use in 5.x, this already deprecated now") }
    Task behavior can also be declared out of the task code block.
    task("task_1", { //This will run during the task configuration section println("This is a simple task.") // The following will run during the task execution section doFirst { println("task_1 doFirst()") } doLast { println("task_1 doLast()") } }) task_1.doFirst{ println("task_1 doFirst() outer") } task_1.doLast{ println("task_1 doLast() outer") }
    I will run the gradle -i task_1 under the root path of gradle-path. The log is here.
    PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle -i task_1 Initialized native services in: C:\GradleRepository\native Initialized jansi services in: C:\GradleRepository\native Received JVM installation metadata from 'C:\Software\jdk17': {JAVA_HOME=C:\Software\jdk17, JAVA_VERSION=17.0.10, JAVA_VENDOR=Oracle Corporation, RUNTIME_NAME=Java(TM) SE Runtime Environment, RUNTIME_VERSION=17.0.10+11-LTS-240, VM_NAME=Java HotSpot(TM) 64-Bit Server VM, VM_VERSION=17.0.10+11-LTS-240, VM_VENDOR=Oracle Corporation, OS_ARCH=amd64} The client will now receive all logging from the daemon (pid: 53944). The daemon log file: C:\GradleRepository\daemon\8.6\daemon-53944.out.log Starting 2nd build in daemon [uptime: 7 mins 25.741 secs, performance: 100%, GC rate: 0.00/s, heap usage: 0% of 512 MiB, non-heap usage: 13% of 384 MiB] Using 24 worker leases. Now considering [C:\GitRepository\Daydayup\Gradle\gradle-root] as hierarchies to watch Watching the file system is configured to be enabled if available File system watching is active Starting Build Settings evaluated using settings file 'C:\GitRepository\Daydayup\Gradle\gradle-root\settings.gradle'. Projects loaded. Root project using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle'. Included projects: [root project 'gradle-root', project ':sub-project01', project ':sub-project02', project ':sub-project03'] > Configure project : Evaluating root project 'gradle-root' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle'. Compiling build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle' using SubsetScriptTransformer. Compiling build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle' using BuildScriptTransformer. This is a simple task. > Configure project :sub-project01 Evaluating project ':sub-project01' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project01\build.gradle'. > Configure project :sub-project02 Evaluating project ':sub-project02' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project02\build.gradle'. > Configure project :sub-project03 Evaluating project ':sub-project03' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project03\build.gradle'. All projects evaluated. Task name matched 'task_1' Selected primary task 'task_1' from project : Tasks to be executed: [task ':task_1'] Tasks that were excluded: [] Resolve mutations for :task_1 (Thread[Execution worker,5,main]) started. :task_1 (Thread[Execution worker,5,main]) started. > Task :task_1 Caching disabled for task ':task_1' because: Build cache is disabled Task ':task_1' is not up-to-date because: Task has not declared any outputs despite executing actions. task_1 doFirst() outer task_1 doFirst() task_1 doLast() task_1 doLast() outer BUILD SUCCESSFUL in 976ms 1 actionable task: 1 executed Watched directory hierarchies: []
    Case 2:
    def map = new HashMap<String,Object>() map.put("action",{println("task_1 action in map()")}) task(map,"task_1", { //This will run during the task configuration section println("This is a simple task.") // The following will run during the task execution section doFirst { println("task_1 doFirst()") } doLast { println("task_1 doLast()") } }) task_1.doFirst{ println("task_1 doFirst() outer") } task_1.doLast{ println("task_1 doLast() outer") }
    Log is here
    PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle -i task_1 Initialized native services in: C:\GradleRepository\native Initialized jansi services in: C:\GradleRepository\native Received JVM installation metadata from 'C:\Software\jdk17': {JAVA_HOME=C:\Software\jdk17, JAVA_VERSION=17.0.10, JAVA_VENDOR=Oracle Corporation, RUNTIME_NAME=Java(TM) SE Runtime Environment, RUNTIME_VERSION=17.0.10+11-LTS-240, VM_NAME=Java HotSpot(TM) 64-Bit Server VM, VM_VERSION=17.0.10+11-LTS-240, VM_VENDOR=Oracle Corporation, OS_ARCH=amd64} The client will now receive all logging from the daemon (pid: 53944). The daemon log file: C:\GradleRepository\daemon\8.6\daemon-53944.out.log Starting 4th build in daemon [uptime: 1 hrs 8 mins 18.674 secs, performance: 100%, GC rate: 0.00/s, heap usage: 0% of 512 MiB, non-heap usage: 13% of 384 MiB] Using 24 worker leases. Now considering [C:\GitRepository\Daydayup\Gradle\gradle-root] as hierarchies to watch Watching the file system is configured to be enabled if available File system watching is active Starting Build Settings evaluated using settings file 'C:\GitRepository\Daydayup\Gradle\gradle-root\settings.gradle'. Projects loaded. Root project using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle'. Included projects: [root project 'gradle-root', project ':sub-project01', project ':sub-project02', project ':sub-project03'] > Configure project : Evaluating root project 'gradle-root' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle'. This is a simple task. > Configure project :sub-project01 Evaluating project ':sub-project01' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project01\build.gradle'. > Configure project :sub-project02 Evaluating project ':sub-project02' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project02\build.gradle'. > Configure project :sub-project03 Evaluating project ':sub-project03' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project03\build.gradle'. All projects evaluated. Task name matched 'task_1' Selected primary task 'task_1' from project : Tasks to be executed: [task ':task_1'] Tasks that were excluded: [] Resolve mutations for :task_1 (Thread[Execution worker,5,main]) started. :task_1 (Thread[Execution worker,5,main]) started. > Task :task_1 Caching disabled for task ':task_1' because: Build cache is disabled Task ':task_1' is not up-to-date because: Task has not declared any outputs despite executing actions. task_1 doFirst() outer task_1 doFirst() task_1 action in map() task_1 doLast() task_1 doLast() outer BUILD SUCCESSFUL in 874ms 1 actionable task: 1 executed Watched directory hierarchies: []

    11.2 Understanding Dependencies Between Tasks

    Many times, a task requires another task to run first. If task B uses the output of task A, then task A must complete before task B begins. There are 4 types of dependencies
    Parameters Dependencies
    // Task Dependencies task A { doLast { println "This is TaskA" } } task B { doLast { println "This is TaskB" } } task C(dependsOn:['A','B']){ doLast { println "This is TaskC" } }
    The log is here
    PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle -i C Initialized native services in: C:\GradleRepository\native Initialized jansi services in: C:\GradleRepository\native Received JVM installation metadata from 'C:\Software\jdk17': {JAVA_HOME=C:\Software\jdk17, JAVA_VERSION=17.0.10, JAVA_VENDOR=Oracle Corporation, RUNTIME_NAME=Java(TM) SE Runtime Environment, RUNTIME_VERSION=17.0.10 +11-LTS-240, VM_NAME=Java HotSpot(TM) 64-Bit Server VM, VM_VERSION=17.0.10+11-LTS-240, VM_VENDOR=Oracle Corporation, OS_ARCH=amd64} Removing daemon from the registry due to communication failure. Daemon information: DaemonInfo{pid=53944, a ddress=[8940263b-6149-4fed-b7da-0059f87154ae port:9718, addresses:[/127.0.0.1]], state=Idle, lastBusy=17166 69901931, context=DefaultDaemonContext[uid=88fcf08a-0743-4169-b98a-1276c7482da8,javaHome=C:\Software\jdk17, daemonRegistryDir=C:\GradleRepository\daemon,pid=53944,idleTimeout=10800000,priority=NORMAL,applyInstrument ationAgent=true,daemonOpts=--add-opens=java.base/java.util=ALL-UNNAMED,--add-opens=java.base/java.lang=ALL- UNNAMED,--add-opens=java.base/java.lang.invoke=ALL-UNNAMED,--add-opens=java.prefs/java.util.prefs=ALL-UNNAM ED,--add-opens=java.base/java.nio.charset=ALL-UNNAMED,--add-opens=java.base/java.net=ALL-UNNAMED,--add-open s=java.base/java.util.concurrent.atomic=ALL-UNNAMED,-XX:MaxMetaspaceSize=384m,-XX:+HeapDumpOnOutOfMemoryError,-Xms256m,-Xmx512m,-Dfile.encoding=GBK,-Duser.country=CN,-Duser.language=zh,-Duser.variant]} Removing 0 daemon stop events from registry Previous Daemon (53944) stopped at Sun May 26 11:33:00 BST 2024 by user or operating system Starting a Gradle Daemon, 1 incompatible and 1 stopped Daemons could not be reused, use --status for details Starting process 'Gradle build daemon'. Working directory: C:\GradleRepository\daemon\8.6 Command: C:\Software\jdk17\bin\java.exe --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNA MED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED - -add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=ja va.base/java.util.concurrent.atomic=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError - Xms256m -Xmx512m -Dfile.encoding=GBK -Duser.country=CN -Duser.language=zh -Duser.variant -cp C:\Software\gr adle-8.6-bin\gradle-8.6\lib\gradle-launcher-8.6.jar -javaagent:C:\Software\gradle-8.6-bin\gradle-8.6\lib\agents\gradle-instrumentation-agent-8.6.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.6 Successfully started process 'Gradle build daemon' An attempt to start the daemon took 1.191 secs. The client will now receive all logging from the daemon (pid: 55388). The daemon log file: C:\GradleRepository\daemon\8.6\daemon-55388.out.log Starting build in new daemon [memory: 512 MiB] Using 24 worker leases. Received JVM installation metadata from 'C:\Software\jdk17': {JAVA_HOME=C:\Software\jdk17, JAVA_VERSION=17.0.10, JAVA_VENDOR=Oracle Corporation, RUNTIME_NAME=Java(TM) SE Runtime Environment, RUNTIME_VERSION=17.0.10 +11-LTS-240, VM_NAME=Java HotSpot(TM) 64-Bit Server VM, VM_VERSION=17.0.10+11-LTS-240, VM_VENDOR=Oracle Corporation, OS_ARCH=amd64} Watching the file system is configured to be enabled if available Now considering [C:\GitRepository\Daydayup\Gradle\gradle-root] as hierarchies to watch File system watching is active Starting Build Settings evaluated using settings file 'C:\GitRepository\Daydayup\Gradle\gradle-root\settings.gradle'. Projects loaded. Root project using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle' Included projects: [root project 'gradle-root', project ':sub-project01', project ':sub-project02', project ':sub-project03'] > Configure project : Evaluating root project 'gradle-root' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle'. Compiling build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle' using SubsetScriptTransformer. Compiling build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle' using BuildScriptTransformer. This is a simple task. > Configure project :sub-project01 Evaluating project ':sub-project01' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project01\build.gradle'. > Configure project :sub-project02 Evaluating project ':sub-project02' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project02\build.gradle'. > Configure project :sub-project03 Evaluating project ':sub-project03' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project03\build.gradle'. All projects evaluated. Task name matched 'C' Selected primary task 'C' from project : Tasks to be executed: [task ':A', task ':B', task ':C'] Tasks that were excluded: [] Resolve mutations for :A (Thread[Execution worker,5,main]) started. :A (Thread[Execution worker,5,main]) started. > Task :A Caching disabled for task ':A' because: Build cache is disabled Task ':A' is not up-to-date because: Task has not declared any outputs despite executing actions. This is TaskA Resolve mutations for :B (Thread[Execution worker,5,main]) started. :B (Thread[Execution worker,5,main]) started. > Task :B Caching disabled for task ':B' because: Build cache is disabled Task ':B' is not up-to-date because: Task has not declared any outputs despite executing actions. This is TaskB Resolve mutations for :C (Thread[Execution worker,5,main]) started. :C (Thread[Execution worker,5,main]) started. > Task :C Caching disabled for task ':C' because: Build cache is disabled Task ':C' is not up-to-date because: Task has not declared any outputs despite executing actions. This is TaskC BUILD SUCCESSFUL in 4s 3 actionable tasks: 3 executed Watched directory hierarchies: []
    Internal Dependencies
    task C_2 { dependsOn=['A','B'] doLast { println "This is Task C_2" } }
    The log is here
    PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle -i C_2 Initialized native services in: C:\GradleRepository\native Initialized jansi services in: C:\GradleRepository\native Received JVM installation metadata from 'C:\Software\jdk17': {JAVA_HOME=C:\Software\jdk17, JAVA_VERSION=17.0.10, JAVA_VENDOR=Oracle Corporation, RUNTIME_NAME=Java(TM) SE Runtime Environment, RUNTIME_VERSION=17.0.10+11-LTS-240, VM_NAME=Java HotSpot(TM) 64-Bit Server VM, VM_VERSION=17.0.10+11-LTS-240, VM_VENDOR=Oracle Corporation, OS_ARCH=amd64} The client will now receive all logging from the daemon (pid: 55388). The daemon log file: C:\GradleRepository\daemon\8.6\daemon-55388.out.log Starting 2nd build in daemon [uptime: 3 mins 2.685 secs, performance: 100%, GC rate: 0.00/s, heap usage: 0% of 512 MiB, non-heap usage: 13% of 384 MiB] Using 24 worker leases. Now considering [C:\GitRepository\Daydayup\Gradle\gradle-root] as hierarchies to watch Watching the file system is configured to be enabled if available File system watching is active Starting Build Settings evaluated using settings file 'C:\GitRepository\Daydayup\Gradle\gradle-root\settings.gradle'. Projects loaded. Root project using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle'. Included projects: [root project 'gradle-root', project ':sub-project01', project ':sub-project02', project ':sub-project03'] > Configure project : Evaluating root project 'gradle-root' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle'. Compiling build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle' using SubsetScriptTransformer. Compiling build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle' using BuildScriptTransformer. This is a simple task. > Configure project :sub-project01 Evaluating project ':sub-project01' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project01\build.gradle'. > Configure project :sub-project02 Evaluating project ':sub-project02' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project02\build.gradle'. > Configure project :sub-project03 Evaluating project ':sub-project03' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project03\build.gradle'. All projects evaluated. Task name matched 'C_2' Selected primary task 'C_2' from project : Tasks to be executed: [task ':A', task ':B', task ':C_2'] Tasks that were excluded: [] Resolve mutations for :A (Thread[Execution worker,5,main]) started. :A (Thread[Execution worker Thread 13,5,main]) started. > Task :A Caching disabled for task ':A' because: Build cache is disabled Task ':A' is not up-to-date because: Task has not declared any outputs despite executing actions. This is TaskA Resolve mutations for :B (Thread[Execution worker Thread 13,5,main]) started. :B (Thread[Execution worker Thread 13,5,main]) started. > Task :B Caching disabled for task ':B' because: Build cache is disabled Task ':B' is not up-to-date because: Task has not declared any outputs despite executing actions. This is TaskB Resolve mutations for :C_2 (Thread[Execution worker Thread 13,5,main]) started. :C_2 (Thread[Execution worker Thread 13,5,main]) started. > Task :C_2 Caching disabled for task ':C_2' because: Build cache is disabled Task ':C_2' is not up-to-date because: Task has not declared any outputs despite executing actions. This is Task C_2 BUILD SUCCESSFUL in 1s 3 actionable tasks: 3 executed Watched directory hierarchies: []
    External Dependencies
    task C_3 { doLast { println "This is Task C_3" } } C_3.dependsOn=['A','B']
    The log is here
    PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle -i C_3 Initialized native services in: C:\GradleRepository\native Initialized jansi services in: C:\GradleRepository\native Received JVM installation metadata from 'C:\Software\jdk17': {JAVA_HOME=C:\Software\jdk17, JAVA_VERSION=17.0.10, JAVA_VENDOR=Oracle Corporation, RUNTIME_NAME=Java(TM) SE Runtime Environment, RUNTIME_VERSION=17.0.10+11-LTS-240, VM_NAME=Java HotSpot(TM) 64-Bit Server VM, VM_VERSION=17.0.10+11-LTS-240, VM_VENDOR=Oracle Corporation, OS_ARCH=amd64} The client will now receive all logging from the daemon (pid: 55388). The daemon log file: C:\GradleRepository\daemon\8.6\daemon-55388.out.log Starting 4th build in daemon [uptime: 5 mins 27.939 secs, performance: 100%, GC rate: 0.00/s, heap usage: 0% of 512 MiB, non-heap usage: 13% of 384 MiB] Using 24 worker leases. Now considering [C:\GitRepository\Daydayup\Gradle\gradle-root] as hierarchies to watch Watching the file system is configured to be enabled if available File system watching is active Starting Build Settings evaluated using settings file 'C:\GitRepository\Daydayup\Gradle\gradle-root\settings.gradle'. Projects loaded. Root project using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle'. Included projects: [root project 'gradle-root', project ':sub-project01', project ':sub-project02', project ':sub-project03'] > Configure project : Evaluating root project 'gradle-root' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle'. This is a simple task. > Configure project :sub-project01 Evaluating project ':sub-project01' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project01\build.gradle'. > Configure project :sub-project02 Evaluating project ':sub-project02' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project02\build.gradle'. > Configure project :sub-project03 Evaluating project ':sub-project03' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project03\build.gradle'. All projects evaluated. Task name matched 'C_3' Selected primary task 'C_3' from project : Tasks to be executed: [task ':A', task ':B', task ':C_3'] Tasks that were excluded: [] Resolve mutations for :A (Thread[Execution worker,5,main]) started. :A (Thread[Execution worker Thread 8,5,main]) started. > Task :A Caching disabled for task ':A' because: Build cache is disabled Task ':A' is not up-to-date because: Task has not declared any outputs despite executing actions. This is TaskA Resolve mutations for :B (Thread[Execution worker Thread 8,5,main]) started. :B (Thread[Execution worker Thread 8,5,main]) started. > Task :B Caching disabled for task ':B' because: Build cache is disabled Task ':B' is not up-to-date because: Task has not declared any outputs despite executing actions. This is TaskB Resolve mutations for :C_3 (Thread[Execution worker Thread 8,5,main]) started. :C_3 (Thread[Execution worker Thread 8,5,main]) started. > Task :C_3 Caching disabled for task ':C_3' because: Build cache is disabled Task ':C_3' is not up-to-date because: Task has not declared any outputs despite executing actions. This is Task C_3 BUILD SUCCESSFUL in 887ms 3 actionable tasks: 3 executed Watched directory hierarchies: []
    Cross-project dependencies
    Create a task in gradle.build of sub-project01
    task cross_project_task { doLast { println "This is task in sub-project01" } }
    Create a task in gradle.build of gradle-root
    task cross_project_task_2 { dependsOn(":sub-project01:cross_project_task") doLast { println "This is task in gradle-root" } }
    The log is here
    PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle -i cross_project_task_2 Initialized native services in: C:\GradleRepository\native Initialized jansi services in: C:\GradleRepository\native Received JVM installation metadata from 'C:\Software\jdk17': {JAVA_HOME=C:\Software\jdk17, JAVA_VERSION=17.0.10, JAVA_VENDOR=Oracle Corporation, RUNTIME_NAME=Java(TM) SE Runtime Environment, RUNTIME_VERSION=17.0.10+11-LTS-240, VM_NAME=Java HotSpot(TM) 64-Bit Server VM, VM_VERSION=17.0.10+11-LTS-240, VM_VENDOR=Oracle Corporation, OS_ARCH=amd64} The client will now receive all logging from the daemon (pid: 55388). The daemon log file: C:\GradleRepository\daemon\8.6\daemon-55388.out.log Starting 6th build in daemon [uptime: 12 mins 21.522 secs, performance: 100%, GC rate: 0.00/s, heap usage: 0% of 512 MiB, non-heap usage: 13% of 384 MiB] Using 24 worker leases. Now considering [C:\GitRepository\Daydayup\Gradle\gradle-root] as hierarchies to watch Watching the file system is configured to be enabled if available File system watching is active Starting Build Settings evaluated using settings file 'C:\GitRepository\Daydayup\Gradle\gradle-root\settings.gradle'. Projects loaded. Root project using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle'. Included projects: [root project 'gradle-root', project ':sub-project01', project ':sub-project02', project ':sub-project03'] > Configure project : Evaluating root project 'gradle-root' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle'. This is a simple task. > Configure project :sub-project01 Evaluating project ':sub-project01' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project01\build.gradle'. > Configure project :sub-project02 Evaluating project ':sub-project02' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project02\build.gradle'. > Configure project :sub-project03 Evaluating project ':sub-project03' using build file 'C:\GitRepository\Daydayup\Gradle\gradle-root\sub-project03\build.gradle'. All projects evaluated. Task name matched 'cross_project_task_2' Selected primary task 'cross_project_task_2' from project : Tasks to be executed: [task ':sub-project01:cross_project_task', task ':cross_project_task_2'] Tasks that were excluded: [] Resolve mutations for :sub-project01:cross_project_task (Thread[Execution worker,5,main]) started. :sub-project01:cross_project_task (Thread[Execution worker,5,main]) started. > Task :sub-project01:cross_project_task Caching disabled for task ':sub-project01:cross_project_task' because: Build cache is disabled Task ':sub-project01:cross_project_task' is not up-to-date because: Task has not declared any outputs despite executing actions. This is task in sub-project01 Resolve mutations for :cross_project_task_2 (Thread[Execution worker,5,main]) started. :cross_project_task_2 (Thread[Execution worker,5,main]) started. > Task :cross_project_task_2 Caching disabled for task ':cross_project_task_2' because: Build cache is disabled Task ':cross_project_task_2' is not up-to-date because: Task has not declared any outputs despite executing actions. This is task in gradle-root BUILD SUCCESSFUL in 861ms 2 actionable tasks: 2 executed Watched directory hierarchies: []
    Tips: 1. If one task depends on multiple tasks, the execution order of dependent tasks is random. E.g. A depends on B and C, B may be executed first, and C may be executed first as well. 2. Repeatedly dependent tasks will only be executed once. E.g. A depends on B and C, D also depends on C. So C can only be executed once.

    11.3 Task Execution

    gradle dependencies

    PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle dependencies > Configure project : This is a simple task. > Task :dependencies ------------------------------------------------------------ Root project 'gradle-root' ------------------------------------------------------------ annotationProcessor - Annotation processors and their dependencies for source set 'main'. No dependencies compileClasspath - Compile classpath for source set 'main'. No dependencies compileOnly - Compile-only dependencies for the 'main' feature. (n) No dependencies default - Configuration for default artifacts. (n) No dependencies implementation - Implementation dependencies for the 'main' feature. (n) No dependencies mainSourceElements - List of source directories contained in the Main SourceSet. (n) No dependencies runtimeClasspath - Runtime classpath of source set 'main'. No dependencies runtimeElements - Runtime elements for the 'main' feature. (n) No dependencies runtimeOnly - Runtime-only dependencies for the 'main' feature. (n) No dependencies testAnnotationProcessor - Annotation processors and their dependencies for source set 'test'. No dependencies testCompileClasspath - Compile classpath for source set 'test'. +--- org.junit:junit-bom:5.10.0 | +--- org.junit.jupiter:junit-jupiter:5.10.0 (c) | +--- org.junit.jupiter:junit-jupiter-api:5.10.0 (c) | +--- org.junit.jupiter:junit-jupiter-params:5.10.0 (c) | \--- org.junit.platform:junit-platform-commons:1.10.0 (c) \--- org.junit.jupiter:junit-jupiter -> 5.10.0 +--- org.junit:junit-bom:5.10.0 (*) +--- org.junit.jupiter:junit-jupiter-api:5.10.0 | +--- org.junit:junit-bom:5.10.0 (*) | +--- org.opentest4j:opentest4j:1.3.0 | +--- org.junit.platform:junit-platform-commons:1.10.0 | | +--- org.junit:junit-bom:5.10.0 (*) | | \--- org.apiguardian:apiguardian-api:1.1.2 | \--- org.apiguardian:apiguardian-api:1.1.2 \--- org.junit.jupiter:junit-jupiter-params:5.10.0 +--- org.junit:junit-bom:5.10.0 (*) +--- org.junit.jupiter:junit-jupiter-api:5.10.0 (*) \--- org.apiguardian:apiguardian-api:1.1.2 testCompileOnly - Compile only dependencies for source set 'test'. (n) No dependencies testImplementation - Implementation only dependencies for source set 'test'. (n) +--- org.junit:junit-bom:5.10.0 (n) \--- org.junit.jupiter:junit-jupiter (n) testRuntimeClasspath - Runtime classpath of source set 'test'. +--- org.junit:junit-bom:5.10.0 | +--- org.junit.jupiter:junit-jupiter:5.10.0 (c) | +--- org.junit.jupiter:junit-jupiter-api:5.10.0 (c) | +--- org.junit.jupiter:junit-jupiter-params:5.10.0 (c) | +--- org.junit.jupiter:junit-jupiter-engine:5.10.0 (c) | +--- org.junit.platform:junit-platform-commons:1.10.0 (c) | \--- org.junit.platform:junit-platform-engine:1.10.0 (c) \--- org.junit.jupiter:junit-jupiter -> 5.10.0 +--- org.junit:junit-bom:5.10.0 (*) +--- org.junit.jupiter:junit-jupiter-api:5.10.0 | +--- org.junit:junit-bom:5.10.0 (*) | +--- org.opentest4j:opentest4j:1.3.0 | \--- org.junit.platform:junit-platform-commons:1.10.0 | \--- org.junit:junit-bom:5.10.0 (*) +--- org.junit.jupiter:junit-jupiter-params:5.10.0 | +--- org.junit:junit-bom:5.10.0 (*) | \--- org.junit.jupiter:junit-jupiter-api:5.10.0 (*) \--- org.junit.jupiter:junit-jupiter-engine:5.10.0 +--- org.junit:junit-bom:5.10.0 (*) +--- org.junit.platform:junit-platform-engine:1.10.0 | +--- org.junit:junit-bom:5.10.0 (*) | +--- org.opentest4j:opentest4j:1.3.0 | \--- org.junit.platform:junit-platform-commons:1.10.0 (*) \--- org.junit.jupiter:junit-jupiter-api:5.10.0 (*) testRuntimeOnly - Runtime only dependencies for source set 'test'. (n) No dependencies (c) - A dependency constraint, not a dependency. The dependency affected by the constraint occurs elsewhere in the tree. (*) - Indicates repeated occurrences of a transitive dependency subtree. Gradle expands transitive dependen cy subtrees only once per project; repeat occurrences only display the root of the subtree, followed by this annotation. (n) - A dependency or dependency configuration that cannot be resolved. A web-based, searchable dependency report is available by adding the --scan option. Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. For more on this, please refer to https://docs.gradle.org/8.6/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. BUILD SUCCESSFUL in 884ms 1 actionable task: 1 executed

    gradle help --task [Task Name]

    PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle help --task D > Configure project : This is a simple task. > Task :help Detailed task information for D Path :D Type Task (org.gradle.api.Task) Options --rerun Causes the task to be re-run even if up-to-date. Description - Group Self Definition Task Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. For more on this, please refer to https://docs.gradle.org/8.6/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. BUILD SUCCESSFUL in 853ms 1 actionable task: 1 executed

    gradle properties

    PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle properties > Configure project : This is a simple task. > Task :properties ------------------------------------------------------------ Root project 'gradle-root' ------------------------------------------------------------ A: task ':A' B: task ':B' C: task ':C' C_2: task ':C_2' C_3: task ':C_3' D: task ':D' allprojects: [root project 'gradle-root', project ':sub-project01', project ':sub-project02', project ':sub-project03'] ant: org.gradle.api.internal.project.DefaultAntBuilder@39c96b84 antBuilderFactory: org.gradle.api.internal.project.DefaultAntBuilderFactory@53ca7ccb application: extension 'application' applicationDefaultJvmArgs: [] applicationDistribution: org.gradle.api.internal.file.copy.DefaultCopySpec_Decorated@a1d5de2 applicationName: gradle-root archivesBaseName: gradle-root artifacts: org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler_Decorated@785d2620 asDynamicObject: DynamicObject for root project 'gradle-root' autoTargetJvmDisabled: false base: extension 'base' baseClassLoaderScope: org.gradle.api.internal.initialization.MutableClassLoaderScope@a3ae7e4 buildDir: C:\GitRepository\Daydayup\Gradle\gradle-root\build buildFile: C:\GitRepository\Daydayup\Gradle\gradle-root\build.gradle buildPath: : buildScriptSource: org.gradle.groovy.scripts.TextResourceScriptSource@a16ee4c buildTreePath: : buildscript: org.gradle.api.internal.initialization.DefaultScriptHandler_Decorated@6a8450a1 childProjects: {sub-project03=project ':sub-project03', sub-project02=project ':sub-project02', sub-project01=project ':sub-project01'} childProjectsUnchecked: {sub-project01=project ':sub-project01', sub-project02=project ':sub-project02', sub-project03=project ':sub-project03'} class: class org.gradle.api.internal.project.DefaultProject_Decorated classLoaderScope: org.gradle.api.internal.initialization.MutableClassLoaderScope@7bf917f7 clean: task ':clean' components: SoftwareComponent container configurationActions: org.gradle.configuration.project.DefaultProjectConfigurationActionContainer@2621daab configurationTargetIdentifier: org.gradle.configuration.ConfigurationTargetIdentifier$1@1bf824ad configurations: configuration container convention: org.gradle.internal.extensibility.DefaultConvention@53b17e2b conventionMapping: org.gradle.internal.extensibility.ConventionAwareHelper@60449d05 crossProjectModelAccess: org.gradle.api.internal.project.DefaultCrossProjectModelAccess@4818f724 cross_project_task_2: task ':cross_project_task_2' defaultArtifacts: extension 'defaultArtifacts' defaultTasks: [] deferredProjectConfiguration: org.gradle.api.internal.project.DeferredProjectConfiguration@121f6fc6 dependencies: org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler_Decorated@4a871b88 dependencyFactory: org.gradle.api.internal.artifacts.DefaultDependencyFactory@eef0b68 dependencyLocking: org.gradle.internal.locking.DefaultDependencyLockingHandler_Decorated@1c16c46 dependencyMetaDataProvider: org.gradle.internal.service.scopes.ProjectScopeServices$ProjectBackedModuleMetaDataProvider@68c952e7 depth: 0 description: null detachedState: false displayName: root project 'gradle-root' distributions: Distribution container distsDirName: distributions distsDirectory: extension 'base' property 'distsDirectory' docsDir: C:\GitRepository\Daydayup\Gradle\gradle-root\build\docs docsDirName: docs executableDir: bin ext: org.gradle.internal.extensibility.DefaultExtraPropertiesExtension@5c765f04 extensions: org.gradle.internal.extensibility.DefaultConvention@53b17e2b fileOperations: org.gradle.api.internal.file.DefaultFileOperations@2537cfeb fileResolver: org.gradle.api.internal.file.BaseDirFileResolver@198e6f30 gradle: build 'gradle-root' group: com.artists identityPath: : inheritedScope: org.gradle.internal.extensibility.ExtensibleDynamicObject$InheritedDynamicObject@66caae78 internalStatus: property(java.lang.Object, fixed(class java.lang.String, integration)) java: extension 'java' javaToolchains: extension 'javaToolchains' layout: org.gradle.api.internal.file.DefaultProjectLayout@13f98da3 libsDirName: libs libsDirectory: extension 'base' property 'libsDirectory' listenerBuildOperationDecorator: org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator@79e49703 logger: org.gradle.internal.logging.slf4j.OutputEventListenerBackedLogger@4aee5f29 logging: org.gradle.internal.logging.services.DefaultLoggingManager@1000f13d mainClassName: com.artists.Main model: root project 'gradle-root' modelIdentityDisplayName: null modelRegistry: org.gradle.model.internal.registry.DefaultModelRegistry@4f4be20b name: gradle-root normalization: org.gradle.normalization.internal.DefaultInputNormalizationHandler_Decorated@12ca386e objects: org.gradle.api.internal.model.DefaultObjectFactory@2ae52a09 owner: root project 'gradle-root' parent: null parentIdentifier: null path: : pluginContext: false pluginManager: org.gradle.api.internal.plugins.DefaultPluginManager_Decorated@3dfbaf71 plugins: [org.gradle.api.plugins.HelpTasksPlugin$Inject@219e5171, org.gradle.buildinit.plugins.BuildInitPlu gin$Inject@305433c2, org.gradle.buildinit.plugins.WrapperPlugin$Inject@4488988a, org.gradle.language.base.p lugins.LifecycleBasePlugin$Inject@3330095c, org.gradle.api.plugins.BasePlugin$Inject@506b09fe, org.gradle.a pi.plugins.JvmEcosystemPlugin$Inject@10bbcc3a, org.gradle.api.plugins.ReportingBasePlugin$Inject@7d0cd783, org.gradle.api.plugins.JvmToolchainsPlugin$Inject@2ad56211, org.gradle.api.plugins.JavaBasePlugin$Inject@bb 63de0, org.gradle.testing.base.plugins.TestSuiteBasePlugin$Inject@4206fdc2, org.gradle.api.plugins.JvmTestS uitePlugin$Inject@634f7b21, org.gradle.api.plugins.JavaPlugin$Inject@173b6b07, org.gradle.api.distribution.plugins.DistributionPlugin$Inject@5a1fe31d, org.gradle.api.plugins.ApplicationPlugin$Inject@25ee31c0] processOperations: org.gradle.process.internal.DefaultExecActionFactory$DecoratingExecActionFactory@2db0497f project: root project 'gradle-root' projectConfigurator: org.gradle.api.internal.project.BuildOperationCrossProjectConfigurator@6e7a0def projectDir: C:\GitRepository\Daydayup\Gradle\gradle-root projectEvaluationBroadcaster: ProjectEvaluationListener broadcast projectEvaluator: org.gradle.configuration.project.LifecycleProjectEvaluator@6d4cc74b projectPath: : properties: {...} providers: org.gradle.api.internal.provider.DefaultProviderFactory_Decorated@d2c6db4 publicType: org.gradle.api.plugins.ApplicationPluginConvention reporting: extension 'reporting' repositories: repository container resources: org.gradle.api.internal.resources.DefaultResourceHandler@227836df rootDir: C:\GitRepository\Daydayup\Gradle\gradle-root rootProject: root project 'gradle-root' rootScript: false script: false scriptHandlerFactory: org.gradle.api.internal.initialization.DefaultScriptHandlerFactory@1c53520a scriptPluginFactory: org.gradle.configuration.ScriptPluginFactorySelector@172eb854 serviceRegistryFactory: org.gradle.internal.service.scopes.BuildScopeServiceRegistryFactory@798136c8 services: ProjectScopeServices sourceCompatibility: 17 sourceSets: SourceSet container standardOutputCapture: org.gradle.internal.logging.services.DefaultLoggingManager@1000f13d state: project state 'EXECUTED' status: integration subprojects: [project ':sub-project01', project ':sub-project02', project ':sub-project03'] targetCompatibility: 17 taskDependencyFactory: org.gradle.api.internal.tasks.DefaultTaskDependencyFactory@1aac29e9 taskThatOwnsThisObject: null task_1: task ':task_1' tasks: task set test: task ':test' testReportDir: C:\GitRepository\Daydayup\Gradle\gradle-root\build\reports\tests testReportDirName: tests testResultsDir: C:\GitRepository\Daydayup\Gradle\gradle-root\build\test-results testResultsDirName: test-results testing: extension 'testing' version: 1.0-SNAPSHOT versionCatalogs: extension 'versionCatalogs' Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. For more on this, please refer to https://docs.gradle.org/8.6/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. BUILD SUCCESSFUL in 891ms 1 actionable task: 1 executed

    gradle run

    Add following configuration into build.gradle
    plugins{ id ‘java’ id ‘application’ } mainClassName=’com.artists.Main’ // Specify main startup class path

    gradle tasks

    If you didn’t specify a group, you won’t see any printed out of your self-definition task in any group in the console. You can use IDEA → Gradle Side bar → Other to see your tasks. If you want to specify a group, you can use the following way.
    // Task Group task D { group "Self Definition Task" doLast { println "This is taskD" } }
    You can see your task under Self Definition Task group right now.
    notion image

    gradle tasks --all

    PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle tasks --all > Configure project : This is a simple task. > Task :tasks ------------------------------------------------------------ Tasks runnable from root project 'gradle-root' ------------------------------------------------------------ Application tasks ----------------- run - Runs this project as a JVM application Build tasks ----------- assemble - Assembles the outputs of this project. sub-project01:assemble - Assembles the outputs of this project. sub-project02:assemble - Assembles the outputs of this project. sub-project03:assemble - Assembles the outputs of this project. build - Assembles and tests this project. sub-project01:build - Assembles and tests this project. sub-project02:build - Assembles and tests this project. sub-project03:build - Assembles and tests this project. buildDependents - Assembles and tests this project and all projects that depend on it. sub-project01:buildDependents - Assembles and tests this project and all projects that depend on it. sub-project02:buildDependents - Assembles and tests this project and all projects that depend on it. sub-project03:buildDependents - Assembles and tests this project and all projects that depend on it. buildNeeded - Assembles and tests this project and all projects it depends on. sub-project01:buildNeeded - Assembles and tests this project and all projects it depends on. sub-project02:buildNeeded - Assembles and tests this project and all projects it depends on. sub-project03:buildNeeded - Assembles and tests this project and all projects it depends on. classes - Assembles main classes. sub-project01:classes - Assembles main classes. sub-project02:classes - Assembles main classes. sub-project03:classes - Assembles main classes. clean - Deletes the build directory. sub-project01:clean - Deletes the build directory. sub-project02:clean - Deletes the build directory. sub-project03:clean - Deletes the build directory. jar - Assembles a jar archive containing the classes of the 'main' feature. sub-project01:jar - Assembles a jar archive containing the classes of the 'main' feature. sub-project02:jar - Assembles a jar archive containing the classes of the 'main' feature. sub-project03:jar - Assembles a jar archive containing the classes of the 'main' feature. testClasses - Assembles test classes. sub-project01:testClasses - Assembles test classes. sub-project02:testClasses - Assembles test classes. sub-project03:testClasses - Assembles test classes. Build Setup tasks ----------------- init - Initializes a new Gradle build. wrapper - Generates Gradle wrapper files. Distribution tasks ------------------ assembleDist - Assembles the main distributions distTar - Bundles the project as a distribution. distZip - Bundles the project as a distribution. installDist - Installs the project as a distribution as-is. Documentation tasks ------------------- javadoc - Generates Javadoc API documentation for the 'main' feature. sub-project01:javadoc - Generates Javadoc API documentation for the 'main' feature. sub-project02:javadoc - Generates Javadoc API documentation for the 'main' feature. sub-project03:javadoc - Generates Javadoc API documentation for the 'main' feature. Help tasks ---------- buildEnvironment - Displays all buildscript dependencies declared in root project 'gradle-root'. sub-project01:buildEnvironment - Displays all buildscript dependencies declared in project ':sub-project01'. sub-project02:buildEnvironment - Displays all buildscript dependencies declared in project ':sub-project02'. sub-project03:buildEnvironment - Displays all buildscript dependencies declared in project ':sub-project03'. dependencies - Displays all dependencies declared in root project 'gradle-root'. sub-project01:dependencies - Displays all dependencies declared in project ':sub-project01'. sub-project02:dependencies - Displays all dependencies declared in project ':sub-project02'. sub-project03:dependencies - Displays all dependencies declared in project ':sub-project03'. dependencyInsight - Displays the insight into a specific dependency in root project 'gradle-root'. sub-project01:dependencyInsight - Displays the insight into a specific dependency in project ':sub-project01'. sub-project02:dependencyInsight - Displays the insight into a specific dependency in project ':sub-project02'. sub-project03:dependencyInsight - Displays the insight into a specific dependency in project ':sub-project03'. help - Displays a help message. sub-project01:help - Displays a help message. sub-project02:help - Displays a help message. sub-project03:help - Displays a help message. javaToolchains - Displays the detected java toolchains. sub-project01:javaToolchains - Displays the detected java toolchains. sub-project02:javaToolchains - Displays the detected java toolchains. sub-project03:javaToolchains - Displays the detected java toolchains. outgoingVariants - Displays the outgoing variants of root project 'gradle-root'. sub-project01:outgoingVariants - Displays the outgoing variants of project ':sub-project01'. sub-project02:outgoingVariants - Displays the outgoing variants of project ':sub-project02'. sub-project03:outgoingVariants - Displays the outgoing variants of project ':sub-project03'. projects - Displays the sub-projects of root project 'gradle-root'. sub-project01:projects - Displays the sub-projects of project ':sub-project01'. sub-project02:projects - Displays the sub-projects of project ':sub-project02'. sub-project03:projects - Displays the sub-projects of project ':sub-project03'. properties - Displays the properties of root project 'gradle-root'. sub-project01:properties - Displays the properties of project ':sub-project01'. sub-project02:properties - Displays the properties of project ':sub-project02'. sub-project03:properties - Displays the properties of project ':sub-project03'. resolvableConfigurations - Displays the configurations that can be resolved in root project 'gradle-root'. sub-project01:resolvableConfigurations - Displays the configurations that can be resolved in project ':sub-project01'. sub-project02:resolvableConfigurations - Displays the configurations that can be resolved in project ':sub-project02'. sub-project03:resolvableConfigurations - Displays the configurations that can be resolved in project ':sub-project03'. tasks - Displays the tasks runnable from root project 'gradle-root' (some of the displayed tasks may belong to subprojects). sub-project01:tasks - Displays the tasks runnable from project ':sub-project01'. sub-project02:tasks - Displays the tasks runnable from project ':sub-project02'. sub-project03:tasks - Displays the tasks runnable from project ':sub-project03'. Self Definition Task tasks -------------------------- D Verification tasks ------------------ check - Runs all checks. sub-project01:check - Runs all checks. sub-project02:check - Runs all checks. sub-project03:check - Runs all checks. test - Runs the test suite. sub-project01:test - Runs the test suite. sub-project02:test - Runs the test suite. sub-project03:test - Runs the test suite. Other tasks ----------- A B C C_2 C_3 compileJava - Compiles main Java source. sub-project01:compileJava - Compiles main Java source. sub-project02:compileJava - Compiles main Java source. sub-project03:compileJava - Compiles main Java source. compileTestJava - Compiles test Java source. sub-project01:compileTestJava - Compiles test Java source. sub-project02:compileTestJava - Compiles test Java source. sub-project03:compileTestJava - Compiles test Java source. components - Displays the components produced by root project 'gradle-root'. [deprecated] sub-project01:components - Displays the components produced by project ':sub-project01'. [deprecated] sub-project02:components - Displays the components produced by project ':sub-project02'. [deprecated] sub-project03:components - Displays the components produced by project ':sub-project03'. [deprecated] sub-project01:cross_project_task cross_project_task_2 dependentComponents - Displays the dependent components of components in root project 'gradle-root'. [deprecated] sub-project01:dependentComponents - Displays the dependent components of components in project ':sub-project01'. [deprecated] sub-project02:dependentComponents - Displays the dependent components of components in project ':sub-project02'. [deprecated] sub-project03:dependentComponents - Displays the dependent components of components in project ':sub-project03'. [deprecated] model - Displays the configuration model of root project 'gradle-root'. [deprecated] sub-project01:model - Displays the configuration model of project ':sub-project01'. [deprecated] sub-project02:model - Displays the configuration model of project ':sub-project02'. [deprecated] sub-project03:model - Displays the configuration model of project ':sub-project03'. [deprecated] prepareKotlinBuildScriptModel processResources - Processes main resources. sub-project01:processResources - Processes main resources. sub-project02:processResources - Processes main resources. sub-project03:processResources - Processes main resources. processTestResources - Processes test resources. sub-project01:processTestResources - Processes test resources. sub-project02:processTestResources - Processes test resources. sub-project03:processTestResources - Processes test resources. startScripts - Creates OS specific scripts to run the project as a JVM application. task_1 Rules ----- Pattern: clean<TaskName>: Cleans the output files of a task. Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration. Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. For more on this, please refer to https://docs.gradle.org/8.6/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. BUILD SUCCESSFUL in 922ms 1 actionable task: 1 executed

    gradle tasks --group="[Group Name]"

    PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle tasks --group="Self Definition Task" > Configure project : This is a simple task. > Task :tasks ------------------------------------------------------------ Tasks runnable from root project 'gradle-root' ------------------------------------------------------------ Self Definition Task tasks -------------------------- D To see all tasks and more detail, run gradle tasks --all To see more detail about a task, run gradle help --task <task> Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. For more on this, please refer to https://docs.gradle.org/8.6/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. BUILD SUCCESSFUL in 877ms 1 actionable task: 1 executed

    -h, --help

    PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle --help To see help contextual to the project, use gradle help USAGE: gradle [option...] [task...] -?, -h, --help Shows this help message. -a, --no-rebuild Do not rebuild project dependencies. -b, --build-file Specify the build file. [deprecated] --build-cache Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds. --no-build-cache Disables the Gradle build cache. -c, --settings-file Specify the settings file. [deprecated] --configuration-cache Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds. --no-configuration-cache Disables the configuration cache. --configuration-cache-problems Configures how the configuration cache handles problems (fail or warn). Defaults to fail. --configure-on-demand Configure necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds. [incubating] --no-configure-on-demand Disables the use of configuration on demand. [incubating] --console Specifies which type of console output to generate. Values are 'plain', 'auto' (default), 'rich' or 'verbose'. --continue Continue task execution after a task failure. --no-continue Stop task execution after a task failure. -D, --system-prop Set system property of the JVM (e.g. -Dmyprop=myvalue). -d, --debug Log in debug mode (includes normal stacktrace). --daemon Uses the Gradle daemon to run the build. Starts the daemon if not running. --no-daemon Do not use the Gradle daemon to run the build. Useful occasionally if you have configured Gradle to always run with the daemon by default. --export-keys Exports the public keys used for dependency verification. -F, --dependency-verification Configures the dependency verification mode. Values are 'strict', 'lenient' or 'off'. --foreground Starts the Gradle daemon in the foreground. -g, --gradle-user-home Specifies the Gradle user home directory. Defaults to ~/.gradle -I, --init-script Specify an initialization script. -i, --info Set log level to info. --include-build Include the specified build in the composite. -M, --write-verification-metadata Generates checksums for dependencies used in the project (comma-separated list) -m, --dry-run Run the builds with all task actions disabled. --max-workers Configure the number of concurrent workers Gradle is allowed to use. --offline Execute the build without accessing network resources. -P, --project-prop Set project property for the build script (e.g. -Pmyprop=myvalue). -p, --project-dir Specifies the start directory for Gradle. Defaults to current directory. --parallel Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use. --no-parallel Disables parallel execution to build projects. --priority Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Values are 'normal' (default) or 'low' --profile Profile build execution time and generates a report in the <build_dir>/reports/profile directory. --project-cache-dir Specify the project-specific cache directory. Defaults to .gradle in the root project directory. -q, --quiet Log errors only. --refresh-keys Refresh the public keys used for dependency verification. --rerun-tasks Ignore previously cached task results. -S, --full-stacktrace Print out the full (very verbose) stacktrace for all exceptions. -s, --stacktrace Print out the stacktrace for all exceptions. --scan Creates a build scan. Gradle will emit a warning if the build scan plugin has not been applied. (https://gradle.com/build-scans) --no-scan Disables the creation of a build scan. For more information about build scans, please visit https://gradle.com/build-scans. --status Shows status of running and recently stopped Gradle daemon(s). --stop Stops the Gradle daemon if it is running. -t, --continuous Enables continuous build. Gradle does not exit and will re-execute tasks when task file inputs change. -U, --refresh-dependencies Refresh the state of dependencies. --update-locks Perform a partial update of the dependency lock, letting passed in module notations change version. [incubating] -V, --show-version Print version info and continue. -v, --version Print version info and exit. -w, --warn Set log level to warn. --warning-mode Specifies which mode of warnings to generate. Values are 'all', 'fail', 'summary'(default) or 'none' --watch-fs Enables watching the file system for changes, allowing data about the file system to be re-used for the next build. --no-watch-fs Disables watching the file system. --write-locks Persists dependency resolution for locked configurations, ignoring existing locking information if it exists -x, --exclude-task Specify a task to be excluded from execution. -- Signals the end of built-in options. Gradle parses subsequent parameters as only tasks or task options.

    -v, --version

    PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle -v ------------------------------------------------------------ Gradle 8.6 ------------------------------------------------------------ Build time: 2024-02-02 16:47:16 UTC Revision: d55c486870a0dc6f6278f53d21381396d0741c6e Kotlin: 1.9.20 Groovy: 3.0.17 Ant: Apache Ant(TM) version 1.10.13 compiled on January 4 2023 JVM: 17.0.10 (Oracle Corporation 17.0.10+11-LTS-240) OS: Windows 11 10.0 amd64

    --rerun-tasks

    Gradle automatically handles up-to-date checks for output files and directories, but what if the task output is something else entirely? Perhaps it’s an update to a web service or a database table. Or sometimes you have a task which should always run.
    That’s where the doNotTrackState() method on Task comes in. One can use this to disable up-to-date checks completely for a task, like so:
    tasks.register('alwaysInstrumentClasses', Instrument) { classFiles.from layout.files(tasks.named('compileJava')) destinationDir = file(layout.buildDirectory.dir('instrumented')) doNotTrackState("Instrumentation needs to re-run every time") }
    The log is here
    Output of gradle clean alwaysInstrumentClasses > gradle clean alwaysInstrumentClasses > Task :compileJava > Task :alwaysInstrumentClasses BUILD SUCCESSFUL in 0s 4 actionable tasks: 1 executed, 3 up-to-date

    11.4 Create Task

    There are 2 ways to create tasks
    1. Use task()
    1. Use tasks.register() or tasks.create()
    tasks.create("E"){ doLast { println("This is taskE") } } // register() is delayed creation, tasks will only be created // when needed tasks.register("f"){ doLast{ println("This is taskF") } }
    We can specify task properties.
    Configuration
    Description
    Default Value
    type
    Create based on an existing task. 11.5 Task Type
    DefaultTask
    overwrite
    Replace an exist task or not, used with type
    false
    dependsOn
    Task dependencies
    []
    action
    The action or closure add into task
    null
    description
    Description of a task
    null
    group
    Define the group of a task
    null
    task D { group "Self Definition Task" doLast { println "This is taskD" } } task(group:"artists", description:"This is internal definition of task properties","G") task "H"{ group("artists") description("This is another way to set task properties of task H") } task "I"{} I.group="artists" // Task D belongs to Self Definition Task, we will move it to artists D.group("artists")
    notion image

    11.5 Task Type

    Previously we all used DefaultTask. If we want to complete some specific operations, it would be a little complex. In Gradle, we can specify the task type and then use the corresponding API directly.
    Type
    Description
    Generates parsers from Antlr grammars.
    Provides information about the build environment for the project that the task is associated with.
    Runs Checkstyle against some source files.
    Runs CodeNarc against some source files.
    Copies files into a destination directory. This task can also rename and filter files as it copies. The task implements CopySpec for specifying what to copy.
    Creates start scripts for launching JVM applications.
    Deletes files or directories. Example:
    Assembles an EAR archive.
    Executes a command line process. Example:
    Generates an Ivy XML Module Descriptor file.
    Generates a Maven module descriptor (POM) file.
    Generates build dashboard report.
    Executes a Gradle build.
    Compiles Groovy source files, and optionally, Java source files.
    Generates HTML API documentation for Groovy source, and optionally, Java source.
    Generates an HTML dependency report. This report combines the features of the ASCII dependency report and those of the ASCII dependency insight report. For a given project, it generates a tree of the dependencies of every configuration, and each dependency can be clicked to show the insight of this dependency.
    Task to generate HTML, Xml and CSV reports of Jacoco coverage data.
    Task for verifying code coverage metrics. Fails the task if violations are detected based on specified rules.
    Assembles a JAR archive.
    Compiles Java source files.
    Generates HTML API documentation for Java classes.
    Executes a Java application in a child process.
    Runs a set of static code analysis rules on Java source code files and generates a report of problems found.
    Copies resources from their source to their target directory, potentially processing them. Makes sure no stale resources remain in the target directory.
    Publishes an IvyPublication to an IvyArtifactRepository.
    Compiles Scala source files, and optionally, Java source files.
    Generates HTML API documentation for Scala source files.
    Generates a Gradle project structure.
    A task for creating digital signature files for one or more; tasks, files, publishable artifacts or configurations.
    Synchronizes the contents of a destination directory with some source directories and files.
    Assembles a TAR archive.
    Abstract class for all test tasks.
    Executes JUnit (3.8.x, 4.x or 5.x) or TestNG tests. Test are always run in (one or more) separate JVMs.
    Generates an HTML test report from the results of one or more Test tasks.
    Assembles a WAR archive.
    Generates scripts (for *nix and windows) which allow you to build your project with Gradle, without having to install Gradle.
    Writes a Properties in a way that the results can be expected to be reproducible.
    Assembles a ZIP archive. The default is to compress the contents of the zip.
    /** * Task type * Reference: https://docs.gradle.org/current/dsl/ */ // Delete build directory tasks.register("myClean",Delete){ delete layout.buildDirectory } // Customise a task class CustomTask extends DefaultTask { @TaskAction def doSelf() { println "This is doSelf() in MyTask" } } // def myTask = task MyDefinitionTask(type: CustomTask) def myTask = tasks.create("MyTask", CustomTask) myTask.doFirst() { println "This is doFirst() in MyTask" } myTask.doLast() { println "This is doLast() in MyTask" }

    11.6 Execution Order

    1. dependsOn → Strong Dependence
    1. Task Input or Output
    1. Specify execution order by API
     

    11.7 Dynamically assign tasks

    /** * Dynamically assign tasks * After you define a task, you can use it directly */ 4.times { counter -> tasks.register("task${counter}"){ doLast { println "This is task ${counter}" } } } tasks.named('task0'){dependsOn('task2','task3')}
    The log is here
    PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle task0 > Configure project : This is a simple task. > Task :task2 This is task 2 > Task :task3 This is task 3 > Task :task0 Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. For more on this, please refer to https://docs.gradle.org/8.6/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. BUILD SUCCESSFUL in 1s 3 actionable tasks: 3 executed

    11.8 Closing and opening tasks

    /** * Closing and opening tasks * 1. Internal set enable(false), false means the task will be skipped. * 2. Outer set [task name].enabled = false, false means the task will be skipped. */ task disableTask{ doLast{ println "This task is disable task" } enabled(false) // The default is true } //disableTask.enabled=false

    11.9 Timeout

    Each task will have a timeout to restrict the execution time, the task overtime will be killed. But if you use --continue , the successor tasks will be executed as normal, otherwise it will failed. When we run gradle timeoutTask_1 timeoutTask_2 , it will show build failed. You can also try gradle timeoutTask_1 timeoutTask_2 --continue , it will also show build failed. but the timeoutTask_2 will be executed.
    task timeoutTask_1 { doLast{ Thread.sleep(1000) println "This is task timeoutTask_1" } timeout= Duration.ofMillis(500) } task timeoutTask_2 { doLast{ println "This is task timeoutTask_2" } }

    11.10 Find Task

    There are 2 ways to find task
    1. By name. This only supports finding tasks in the current project.
    1. By path. This can find tasks in specific modules or projects.
    task findTask{ doLast { println "This is a task about finding task." } } tasks.findByName("findTask").doFirst {println "Add doFirst() before findTask byName"} tasks.getByName("findTask").doFirst {println "Add doFirst() before findTask getName"} tasks.findByPath(":findTask").doFirst {println "Add doFirst() before findTask byPath"} tasks.getByPath(":findTask").doFirst {println "Add doFirst() before findTask getPath"}

    11.11 Task does not exist

    When we execute a task which doesn’t exist, it will report an error. How can we print a hint rather than report an error?
    /** * Task doesn't exist * If you run gradle abc taskExist -> report an error in normal * For now it will print the hint, addRule([Description], Closure) * The given rule is invoked when an unknown object is requested by name. * The abc is the unknown object. */ task "taskExist"{ doLast { println "This is taskExist." } } tasks.addRule("[Description of rule]",{ def taskName -> task(taskName){ println "The unknow object is ${taskName}" } })
    Why this rule only take effect on abc rather than taskExist. The official document said “Adds a rule to this collection. The given rule is invoked when an unknown object is requested by name.”

    11.12 OnlyIf

    How to let a task to be executed under a specific condition? Such as the keyword if in Java. There is a onlyIf, abstract fun onlyIf(onlyIfClosure: Closure) In business, when you want to control a JUnit test, you can use this.
    /** * onlyIf * Before you test, please ensure the line 231-235 comment out * first. Why? We can only use 248, and 249 to add a property * to the project. Task is a property of the project object as * well. * gradle onlyIfTask -> will run * gradle propertyExist_3 -> will run */ task "onlyIfTask" { doLast { println "This is onlyIfTask." } } // You can use the following way to add a property to the project object // You can also use gradle onlyIfTask -PpropertyExist=true to add a property to // the project object ext.propertyExist=true ext { propertyExist_2=true } onlyIfTask.onlyIf {project.hasProperty("propertyExist")} task "propertyExist_3" { println "100% task is a property of the project object"} onlyIfTask.onlyIf {project.hasProperty("propertyExist_3")}

    11.13 Default Task

    No tasks names are provided when starting the build, we want it to run a default task. We can use default tasks. Attention, this will be executed when no tasks names provided. What is this means? gradle -q or gradle
    /** * Default task */ task defaultTask{ doLast { println "This is default task" } } task nonDefaultTask{ doLast { println "This is non-default task" } } defaultTasks 'defaultTask'
     

    12. File Operation

    12.1 Local File

    We can use Project.file(java.lang.Object) to create a File Object of Java. Then we can use all APIs of a File object.
    /** * Local File Operation */ // Relative Path File relative = file('src/relativePath.xml') relative.createNewFile() // Absolute Path File absolute = file('C:\\GitRepository\\Daydayup\\Gradle\\gradle-root\\src\\absolutePath.xml') absolute.createNewFile() // New File File newFile = new File('src/newFile.xml') newFile.createNewFile()

    12.2 File Collection

    File collection is a set of file. We can use Project.files(java.lang.Object[]) to create a FileCollection instance.
    /** * File Collection */ FileCollection fileCollection = files('src/fileCollection_1.xml',['src/fileCollection_2.xml','src/fileCollection_3.xml']) fileCollection.forEach { item -> { println(item.name) item.createNewFile() } } // Convert fileCollection to Set Set filesSet = fileCollection.files for (def i in filesSet){ println "fileSet " + i.exists() } Set fileSet_2 = fileCollection as Set for (def i in fileSet_2){ println "fileSet_2 " +i.exists() } // Convert fileCollection to List Set fileList = fileCollection as List // Add or remove file of fileCollection def addFile = fileCollection + files('src/fileCollection_4.xml') def removeFile = fileCollection - files('src/fileCollection_4.xml') addFile.forEach { File item -> { println "AddFile " + item.name }}

    12.3 File Tree

    A file tree is a hierarchical collection of files.
    /** * File Tree * 1. Use path to create file tree object * 2. Use closure to create file tree object * 3. Use path and closure to create file tree */ ConfigurableFileTree configurableFileTree = fileTree('src/main') configurableFileTree.forEach (item->{ println "File tree - ${item.name}" }) // Exclude Main.java -> It won't print anything configurableFileTree.exclude("**/*.java").forEach (item->{ println "File tree exclude - ${item.name}" }) // 2. Use closure to create file tree def tree = fileTree('src/main').include("**/*.java") tree.forEach (item -> {println "Use closure to create file tree - ${item.name}"}) // 3. Use path and closure to create file tree tree = fileTree(dir: 'src/main',include:'**/*.java') tree = fileTree(dir: 'src/main',includes:['**/*.java','**/*.xml'],excludes: '**/*Txt*/**')
     

    12.4 File Copy

    File copy can use Copy Task to copy file, filter file, and rename file. (If you use IDEA, after you run a task, please reload the task and then you can see the files. Or you can go to the target directory in the computer to check.)
    /** * File Copy * from([file path]) * into([directory path]) * 1. If file path is a directory -> copy all files in this directory * 2. If file path is a file -> copy this file * 3. If file path is a zip -> copy file in this zip */ task copyTasks(type:Copy){ // Copy files in the folder. If the folder doesn't exist, it will be ignored. from 'src/main/webapp' // Copy a specific file from 'src/main/java/com/artists/TestCopyFile.csv' // Copy from zip from zipTree('src/main/TestZip.zip') // Copy files to target directory into 'build/copyFile' //into this.buildDir.absolutePath } // only copy .csv file task copyTasks_2(type:Copy){ from 'src/main/java/com/artists/TestCopyFile.csv' from zipTree('src/main/TestZip.zip') include('**/*.csv') // exclude('**/*.csv') into 'build/copyFile_2' } // rename the file task copyTasks_3(type:Copy){ from 'src/main/java/com/artists/TestCopyFile.csv' rename { def fileName -> fileName.replace('CopyFile','CopyFile_3') } into 'build/copyFile_3' } // copy() task copyTasks_4 { copy { from 'src/main/java/com/artists/TestCopyFile.csv' into 'build/copyFile_4' } } // define input & output outside task copyTasks_5 { inputs.file 'src/main/java/com/artists/TestCopyFile.csv' outputs.dir 'build/copyFile_5' doLast{ copy { from 'src/main/java/com/artists/TestCopyFile.csv' into 'build/copyFile_5' } } }

    12.5 Archive File

    Sometime we need to create a zip, jar, war in a task, we can use the following way to do this thing.
    /** * Archive File * archiveTask(type:Zip) -> type is the target type you want to use * Target Zip name = [archiveBaseName]-[archiveAppendix]-[archiveVersion]-[archiveClassifier].[archiveExtension] * Target file path is */ def archivesDirPath = layout.buildDirectory.dir('archiveFile') task archiveTask(type:Zip) { from 'src/main/java/com/artists/TestCopyFile.csv' into 'build' archiveBaseName ='archiveTask' destinationDirectory= archivesDirPath }

    13. Dependencies

    When you execute gradle build , gradle will download the corresponding jar from dependencies repository.
    There are 3 kind of dependencies:
    1. Direct Dependency
    1. Project Dependency
    1. Local Jar Dependency
    /** * There are 3 kind of dependencies: * 1. Direct Dependency -> [Dependency type][Dependency group] [Dependency name][Dependency version] * 2. Project Dependency * 3. Local Jar Dependency -> can use file collection & file tree */ dependencies { testImplementation platform('org.junit:junit-bom:5.10.0') testImplementation 'org.junit.jupiter:junit-jupiter' // 1. Direct Dependency implementation group: 'log4j', name: 'log4j', version: '1.2.17' implementation 'log4j:log4j:1.2.17' // 2. Project Dependency, you must define this module in settings.gradle implementation project(':sub-project01') // 3. Local Jar Dependency // Dependent on mysql.jar under lib, lib and src are the same level directories implementation files('lib/mysql.jar','lib/log4j.jar') // Dependent on all jars under lib directory, can also use excludes implementation fileTree('dir':'lib',includes: ['*.jar']) }

    Dependencies Type

    This is same with the <scope> in maven.
    Dependencies Type
    Description
    compileOnly
    Only use in compile stage but won’t package it. (Provided by Java plugin)
    runtimeOnly
    Only use in runtime stage but won’t use in compile stage. E.g. mysql driver (Provided by Java plugin)
    implementation
    Active in compile and runtime stage. (Provided by Java plugin)
    testCompileOnly
    Only use in compile test stage but won’t use in runtime stage. (Provided by Java plugin)
    testRuntimeOnly
    Only use in runtime test stage but won’t use in compile stage. (Provided by Java plugin)
    testImplementation
    Only for test in [src/test], (Provided by Java Plugin)
    providedCompile
    It is used in the compile and test stages, and the container in the runtime stage already provides corresponding support; there is no need to package it into war. E.g. servlet-api.jar (Provided by war plugin)
    compile
    Compile all dependencies and use in all classpath, and will be packaged. Remove after v7.0
    runtime
    Only use in compile and test stage but not in compile stage. E.g. mysql driver. Remove after v7.0
    compileOnlyApi
    Use in declaring a module and compiling, but not in runtime stage. (Provided by java-library)

    Difference between api and implementation

    compileOnlyApi
    implementation
    Compile
    Dependency Transmission. If the underlying dependencies change, then the upper-level dependencies must also change. So the compilation speed is slower.
    Dependency Transmission. So the compilation speed is faster.
    Runtime
    All class of modules will be loaded.
    All class of modules will be loaded.
    Application Scenario
    Applicable to multi-module dependencies to avoid duplicate dependencies. (Only multiple modules, we need to consider to use compileOnlyApi)
    In most cases use implementation
    Example 1:
    notion image
    If dependency_B changes, dependency_B, dependency_A, and the project will be re-compiled.
    If dependency_D changes, only dependency_D and dependency_C will be re-compiled.
    Example 2:
    • A implementation B, B implementation C, so A can’t use C.
    • A implementation B, B API C, so A can use C.
    • A implementation B, B implementation C, C API D, so B can use D, but A can’t.
    • A implementation B, B API C, C API D, so A can use D.

    Dependencies Conflict

    Example:
    Root project A has 2 sub modules, B and C. B depend on log4j1.4.2, but C depend on log4j 2.2.4 The question is which version project A will use?
    Answer:
    Gradle will use the latest version, for example, the latest version log4j is 3.1, so Gradle will use 3.1 rather than 1.4.2 or 2.2.4. Why Gradle will use latest version? Because most jar backward compatibility. This is a default way, you don’t need to do anything
     
    Method 2:
    Gradle also provide the exclude like Maven
    // Exclude dependencies implementation('org.hibernate:hibernate-core:3.6.3.Final'){ exclude group:'org.slf4j' // You can also use module to exclude the dependency exclude module:'slf4j-api' exclude group:'org.slf4j',module:'slf4j-api' }
    Method 3: (Better not use this way)
    Preventing dependency propagation. When we import a dependency, it will show like the following screenshot.
    notion image
    If we prevent dependency propagation, it will looks like
    notion image
    Method 4: (The official documentation recommends using this method)
    Force a specific version
    notion image
    implementation 'org.slf4j:slf4j-api:1.4.0!!' // + means to find the latest version in repositories{}. // The following 2 ways called dynamic version declaration implementation 'org.slf4j:slf4j-api:+' implementation 'org.slf4j:slf4j-api:latest.integration' // Force a specific version implementation 'org.slf4j:slf4j-api:1.4.0'{ version{ strictly("1.4.0") } }
     

    How do we check which dependency conflicts?

    // When there is dependencies conflict, it will failed during the build stage configurations.all(){ Configuration configuration -> { configuration.resolutionStrategy.failOnVersionConflict() } }

    14. Gradle Plugins

    Q1: Why we use plugins?
    1. Promote code reuse, improve code efficiency.
    1. Promote higher degree of modularization, automation and convenience of projects.
    1. Pluggable expansion project functions.
    Q2: What are plugins for?
    1. Add task into project to help complete test, compile, package.
    1. Can add scope for dependencies.
    1. Can extend new properties, methods, and so on.
    1. Some agreements can be made on the project. E.g. we add java plugin, the convention is that main/java/src is the storage location of the source code.
    notion image
    Script Plugin
    It is essentially a script, such as I define a script_plugin.gradle
    // This is for script_plugin test ext { author = "ArtistS" conf=[ jdkVersion: JavaVersion.VERSION_1_8 ] spring=[ version:'5.0.0' ] }
    And in the build.gradle you can use keyword apply from to import the script.
    // In the build.gradle file /** * Script Plugin * apply from: [file absolute path | relative path] */ apply from:'script_plugin.gradle' task scriptPluginTest{ doLast { println("The author is ${author}, and JDK version is ${conf.jdkVersion}, the spring version is ${spring.version}") } }
    Where we can use script plugin?
    In my opinion, we can use it to manage the whole version we use in the project, we only need to change one version in one file. And we can also use script plugin to manage the application version. In our project, we will have multiple modules, we can use this way to manage the module version in one place.
    Binary Plugin(Object Plugin)
    A plugin implements org.gradle.Plugin interface called Binary Plugin, each Java Gradle Plugin will have a plugin id (This id is unique).
    notion image
    Internal Plugin (Core Plugin)
    If you want to check how many core plugin in the Gradle, you can open the following link .
    // In build.gradle // 1. Use plugins DSL plugins{ id 'java' } // 2. apply(map specific parameters) // apply[plugin id || Full Class Name || Plugin Class Name] apply plugin:'java' // plugin id apply plugin:org.gradle.api.plugins.JavaPlugin // Full Class Name apply plugin:JavaPlugin // Plugin Class Name // 3. apply(closure) apply { plugin 'java' }
    Third Party Plugin
    //Traditional usage -> buidscript tag must be the first tag in build.gradle file buildscript { repositories { maven { url = uri("https://plugins.gradle.org/m2/") } } // import plugins here first dependencies { classpath("uk.gov.hmcts.reform:ccd-gradle-plugin:5.5.6") } } // Then apply plugin apply(plugin = "hmcts.ccd.sdk")// You already import first, no need to write version // Plugin DSL // If the third-party plugin be hosted on the following website, you don't need // to write classpath in the buildscript.https://plugins.gradle.org/ plugins { id("hmcts.ccd.sdk") version "5.5.6" }
    Custom Plugin
    Conclusion: In most cases, we won’t use custom plugin. These plugins can only be used in the current project, and the other projects can’t use.
    // In build.gradle /** * Custom Plugin */ class GreetingPlugin implements Plugin<Project> { void apply(Project project) { project.task('hello') { doLast { println 'Hello from the GreetingPlugin' } } } } // Apply the plugin apply plugin: GreetingPlugin
    You can also use plugin extension.
    interface GreetingPluginExtension { Property<String> getMessage() } class GreetingPlugin implements Plugin<Project> { void apply(Project project) { // Add the 'greeting' extension object def extension = project.extensions.create('greeting', GreetingPluginExtension) // Add a task that uses configuration from the extension object project.task('hello') { doLast { println extension.message.get() } } } } apply plugin: GreetingPlugin // Configure the extension greeting.message = 'Hi from Gradle'
    buildSrc (Only can use in current project)
    buildSrc is the Gradle default directory, Gradle will distinguish this directory when compiling, and compiling the code in it as a plugin.
    1. Create a module named buildSrc(the name must this)
    1. Update the build.gradle
      1. apply plugin:'groovy' // indispensable apply plugin: 'maven-publish' dependencies{ implementation gradleApi() // indispensable implementation localGroovy() // indispensable } repositories { google() jcenter() mavenCentral() // indispensable } // Set the entry as src/main/groovy sourceSets{ main{ groovy{ srcDir 'src/main/groovy' } } }
    1. Create Test.groovy
      1. package com.artists import org.gradle.api.Plugin import org.gradle.api.Project class BuildSrcPlugin implements Plugin<Project>{ @Override void apply(Project project) { // This name can't include _ e.g. Custom_Plugin project.task("globalPlugin"){ doLast{ println("This is global custom plugin!") } } } }
    4. Create resources/META-INF/gradle-plugins/properties under src. And create com.artists.plugin.properties.(This file must be [Package Name of Test.groovy].properties, and [Package Name of Test.groovy] is the id of this plugin)
    notion image
    And update the com.artists.plugin.properties
    # implementation-class=[full class name of the custom plugin class] implementation-class=com.artists.Test
    1. Import the plugin in the module you want to use. E.g. I will add this into the gradle-root
      1. apply plugin: 'BuildSrcPlugin' // Or you can also use this way, if you use // this way you don't need to do step4 /** * Apply Global Custom Plugin */ apply plugin: 'java-gradle-plugin' gradlePlugin { plugins { greeting { // plugin id id = 'BuildSrcPlugin' // implementation class implementationClass = 'com.artists.BuildSrcPlugin' } } }
         
    Custom Plugin (Can use in different project) If you want your custom plugins can use in any project, you should publish it to maven repository.
    1. Create custom plugin as last section buildSrc (Only can use in current project). Here I copy this buildSrc and rename it as global-custom-plugin
    1. Add following code in settings.gradle
      1. include 'global-custom-plugin'
    1. Update build.gradle
      1. apply plugin:'groovy' // indispensable apply plugin:'maven-publish' dependencies{ implementation gradleApi() // indispensable implementation localGroovy() // indispensable } repositories { google() jcenter() mavenCentral() // indispensable } // Set the entry as src/main/groovy sourceSets{ main{ groovy { srcDir 'src/main/groovy' } } } publishing { publications { myLibrary(MavenPublication){ groupId = 'com.artists.plugin' artifactId = 'library' version = '1.0' from components.java // publish jar // from components.web // publish war } } repositories { maven {url "$rootDir/lib/release"} // Publish to private nexus repository // maven { // name = 'myRepo' // repository name (Optional) // url = layout.buildDirectory.dir("repo") // local maven repository // url = 'http://artists/repo' // private maven repository // credentials { // username: 'Allen' // password: 'secret' // } // } } }
    1. Click publish
      1. notion image
    1. Check if the plugin already publish to the target directory or remote repository.
      1. notion image
    1. In the build.gradle of module or project you want to use this plugin.
      1. /** * Custom plugin in all project * buildscript must at top */ buildscript { repositories { maven {url "$rootDir/lib/release"} } dependencies { classpath "com.artists.plugin:library:1.0" } } apply plugin: 'com.artists.plugin'

    15. Publish a project

    notion image
    1. Import maven publish plugin in build.gradle
      1. plugins { id 'java-library' // If publish war, need war plugin id 'maven-publish' }
    1. Add publish code into build.gradle
      1. /** * Publish a project */ publishing { publications { myLibrary(MavenPublication){ groupId='org.gradle.sample' artifactId='library' version='1.0' from components.java // publish jar // from components.web // publish war } } repositories{ // Path of local maven repository: $USER_HOME/.m2/repository mavenLocal() // Publish to private repository maven{ name='myRepo' // Repository name(optional) // Publish address can be local repository or Maven private repository def releasesRepoUrl=layout.buildDirectory.dir('repos/releases') def snapshotsRepoUrl=layout.buildDirectory.dir('repos/snapshots') // url is required not optional url = version.endsWith('SNAPSHOT')?snapshotsRepoUrl:releasesRepoUrl // If you want to publish to remote private maven repository // url = 'http://my.artists/repo' // Credential // credentials { // username = 'joe' // password = 'secret' // } } } }
    1. Click publish button, same with publishing plugin
      1. notion image
    1. If you want to publish the jar or war with doc, please add the following code.
      1. plugins { id 'java-library' } javadoc.options.encoding="UTF-8" java { withJavadocJar() withSourcesJar() } publish{ ... }

    16. Hook

    notion image
    1. Only 1 gradle object in one project.
    1. Each build.gradle will be converted to a Project object.
    1. Each settings.gradle will be converted to a settings object. (In most cases only 1 settings object)
    Example → Simple usage
    1. Add the following code into settings.gradle
      1. gradle.settingsEvaluated { println "Hook1: settingsEvaluated" } gradle.projectsLoaded { println "Hook2: projectLoaded" } def projectName = "" gradle.addProjectEvaluationListener(new ProjectEvaluationListener() { @Override void beforeEvaluate(Project project) { projectName = project.name println "Hook3: ${project.name} Project beforeEvaluate" } @Override void afterEvaluate(Project project, ProjectState state) { println "Hook4: ${project.name} Project afterEvaluate" } }) gradle.beforeProject { println "Hook3_2: ${project.name} beforeProject..." } gradle.afterProject { println "Hook4_2: ${project.name} afterProject..." } def rootProjectName = rootProject.getName() gradle.projectsEvaluated { println "Hook5: ${rootProjectName} projectsEvaluated..." } gradle.taskGraph.whenReady { println "Hook6: ${rootProjectName} whenReady..." } gradle.taskGraph.beforeTask { task -> { println "Hook7: This is the task ${task.name} -> beforeTask" } } gradle.taskGraph.afterTask { task -> { println "Hook8: This is the task ${task.name} -> afterTask" } } gradle.buildFinished { println "Hook9: buildFinished..." }
    1. Add the following code into root build.gradle
      1. /** * Hook test */ task Hook_A { println "root Hook_A" doFirst { println "root Hook_A doFirst" } doLast{ println "root Hook_A doLast" } }
    1. Add the following code into sub-project01 build.gradle
      1. /** * Hook test */ task Hook_B { println "sub-project01 Hook_B" doFirst { println "sub-project01 Hook_B doFirst" } doLast{ println "sub-project01 Hook_B doLast" } }
    1. Add the following code into sub-project02 build.gradle
      1. /** * Hook test */ task Hook_C { dependsOn 'Hook_D' println "sub-project02 Hook_C" doFirst { println "sub-project02 Hook_C doFirst" } doLast{ println "sub-project02 Hook_C doLast" } } task Hook_D { println "sub-project02 Hook_D" doFirst { println "sub-project02 Hook_D doFirst" } doLast{ println "sub-project02 Hook_D doLast" } }
    1. Execute gradle Hook_C
      1. PS C:\GitRepository\Daydayup\Gradle\gradle-root> gradle Hook_C Configuration on demand is an incubating feature. Hook1: settingsEvaluated Hook2: projectLoaded > Configure project : Hook3: gradle-root Project beforeEvaluate Hook3_2: gradle-root beforeProject... This is a simple task. 100% task is a property of the project object fileCollection_1.xml fileCollection_2.xml fileCollection_3.xml fileSet true fileSet true fileSet true fileSet_2 true fileSet_2 true fileSet_2 true AddFile fileCollection_1.xml AddFile fileCollection_2.xml AddFile fileCollection_3.xml AddFile fileCollection_4.xml File tree - Main.java File tree - TestCopyFile.csv File tree - TestFileTree.java File tree - TestFileTreeTxt.csv File tree - fileCopy.csv File tree - TestZip.zip File tree exclude - TestCopyFile.csv File tree exclude - TestFileTreeTxt.csv File tree exclude - fileCopy.csv File tree exclude - TestZip.zip Use closure to create file tree - Main.java Use closure to create file tree - TestFileTree.java root Hook_A Hook4: gradle-root Project afterEvaluate Hook4_2: gradle-root afterProject... > Configure project :global-custom-plugin Hook3: global-custom-plugin Project beforeEvaluate Hook3_2: global-custom-plugin beforeProject... Hook4: global-custom-plugin Project afterEvaluate Hook4_2: global-custom-plugin afterProject... > Configure project :sub-project01 Hook3: sub-project01 Project beforeEvaluate Hook3_2: sub-project01 beforeProject... sub-project01 Hook_B Hook4: sub-project01 Project afterEvaluate Hook4_2: sub-project01 afterProject... > Configure project :sub-project02 Hook3: sub-project02 Project beforeEvaluate Hook3_2: sub-project02 beforeProject... sub-project02 Hook_C sub-project02 Hook_D Hook4: sub-project02 Project afterEvaluate Hook4_2: sub-project02 afterProject... > Configure project :sub-project03 Hook3: sub-project03 Project beforeEvaluate Hook3_2: sub-project03 beforeProject... Hook4: sub-project03 Project afterEvaluate Hook4_2: sub-project03 afterProject... Hook5: gradle-root projectsEvaluated... Hook6: gradle-root whenReady... > Task :sub-project02:Hook_D Hook7: This is the task Hook_D -> beforeTask sub-project02 Hook_D doFirst sub-project02 Hook_D doLast Hook8: This is the task Hook_D -> afterTask > Task :sub-project02:Hook_C Hook7: This is the task Hook_C -> beforeTask sub-project02 Hook_C doFirst sub-project02 Hook_C doLast Hook8: This is the task Hook_C -> afterTask Hook9: buildFinished...
    Example → Calculate time of each stage
    Add the following code into settings.gradle
    /** * Example -> Calculate time of each stage */ def projectName = rootProject.getName() long beginOfSetting = System.currentTimeMillis() def beginOfConfig def configHasBegin = false def beginOfProjectConfig = new HashMap() def beginOfTaskExecute gradle.projectsLoaded { println "${projectName} spends ${System.currentTimeMillis() - beginOfSetting} ms on initialization stage" } gradle.beforeProject { Project project -> if(!configHasBegin){ configHasBegin = true beginOfConfig = System.currentTimeMillis() } beginOfProjectConfig.put(project,System.currentTimeMillis()) } gradle.afterProject { Project project -> def begin = beginOfProjectConfig.get(project) if(project.getName() == projectName){ println "root project ${projectName} spends ${System.currentTimeMillis()- begin} ms on cnfiguration stage" }else{ println "sub project ${project.name} spends ${System.currentTimeMillis() - begin} ms on configuration stage" } } gradle.taskGraph.whenReady { println "Whole ${projectName} spends ${System.currentTimeMillis() - beginOfConfig} ms on configuration stage" beginOfTaskExecute = System.currentTimeMillis() } gradle.taskGraph.beforeTask { Task task -> { task.doFirst { task.ext.beginOfTask = System.currentTimeMillis() } task.doLast{ println "${task.name} spends ${System.currentTimeMillis() - task.ext.beginOfTask} ms" } } } gradle.buildFinished { println "Execution stage spends ${System.currentTimeMillis() - beginOfTaskExecute} ms" println "The whole building stage spends ${System.currentTimeMillis() - beginOfSetting} ms" }
    Example → Add listener to check task DAG
    gradle.taskGraph.addTaskExecutionGraphListener {new TaskExecutionGraphListener(){ @Override void graphPopulated(TaskExecutionGraph taskExecutionGraph){ taskExecutionGraph.allTasks.forEach { Task task -> { taskExecutionGraph.allTasks.forEach { Task releaseTask -> { println "Artist:"+ releaseTask.getProject().name + ":" + releaseTask.name } } } } } }}

    N. gradle.properties

    All configurations in gradle.properties are global and can be used directly in build.gradle of each module. Some data we don't want others to see, we can put into this file, and don't upload this file to EDH. This file can also change and unify some properties to improve# development efficiency.
    # JVM heap size (If you want to run faster, you can increase this value) Dorg.gradle.jvmargs=-Xmx5120m -XX:MaxPermSize=1280m -Dfile.encoding=UTF-8 # Open daemon,the next build will use this daemon as well rather than fork a new gradle process. #Dorg.gradle.daemon=true # Load on demand #Dorg.gradle.configureondemand=true # Parallel compile #Dorg.gradle.parallel=true # Open Gradle cache #Dorg.gradle.caching=true # Workers # max-workers=8

    N.1 build.gradle

    // Specify the JDK version to compile source code(Can only use with java plugin) // Related to compile env sourceCompatibility = 1.8 // Generate specific JDK version's class file(Can only use with Java plugin) // Related to running env targetCompatibility = 1.8 // Compile character set encoding compileJava.options.encoding "UTF-8" // Test character set encoding compileTestJava.options.encoding "UTF-8" // Compile JAVA file with UTF-8 -> source code tasks.withType(JavaCompile) { options.encoding = "UTF-8" } // Compile JAVA file with UTF-8 -> doc tasks.withType(Javadoc) { options.encoding "UTF-8" } /** * Repositories * Gradle will try to find the dependencies by the order */ repositories { maven { url 'file:///D:/repos/mavenrepos3.5.4' } maven { url "$rootDir/lib/release" } // Try to find dependencies in local Maven Repositories mavenLocal() // Try to find dependencies in third-party repositories and private repositories maven { name "Alibaba"; url "https://maven.aliyun.com/repository/public" } maven { name "Bestek"; url "https://nexus.bsdn.org/content/groups/public" } // Try to find dependencies in remote Maven repositories mavenCentral() // Try to find dependencies in google repositories google() } /** * allprojects * allprojects will configure root project + child project * It will print * gradle-root * buildSrc * gloal-custom-plugin * sub-project01 * sub-project02 * sub-project03 */ allprojects { tasks.create('configureAllProject') { println "project name is $project.name" } } /** * Sub-projects * subprojects will configure all child projects * It will print * buildSrc * gloal-custom-plugin * sub-project01 * sub-project02 * sub-project03 */ subprojects { tasks.create('configureAllProject') { println "project name is $project.name" } } /** * project * If you configure repositories and dependencies in the root * project, these dependencies can only be used in the root * project. If you want to use in the child project, you should * configure them by project. * You can use project('[sub project name exist in settings.gradle]') * to configure a specific project. * E.g. Add a dependencies into the sub-project01 */ project('sub-project01'){ apply plugin: 'java' dependencies { implementation 'log4j:log4j:1.2.17' } }