COMP529-Gradle
  • NEW!
    NEW!  Connect Ideas Across Notes
    Save time and share insights. With Paragraph Citation, you can quote others’ work with source info built in. If someone cites your note, you’ll see a card showing where it’s used—bringing notes closer together.
    Got it
        • Sharing URL Link copied
        • /edit
        • View mode
          • Edit mode
          • View mode
          • Book mode
          • Slide mode
          Edit mode View mode Book mode Slide mode
        • Customize slides
        • Note Permission
        • Read
          • Owners
          • Signed-in users
          • Everyone
          Owners Signed-in users Everyone
        • Write
          • Owners
          • Signed-in users
          • Everyone
          Owners Signed-in users Everyone
        • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invite by email
        Invitee

        This note has no invitees

      • Publish Note

        Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

        Your note will be visible on your profile and discoverable by anyone.
        Your note is now live.
        This note is visible on your profile and discoverable online.
        Everyone on the web can find and read all notes of this public team.

        Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

        Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

        Explore these features while you wait
        Complete general settings
        Bookmark and like published notes
        Write a few more notes
        Complete general settings
        Write a few more notes
        See published notes
        Unpublish note
        Please check the box to agree to the Community Guidelines.
        View profile
      • Commenting
        Permission
        Disabled Forbidden Owners Signed-in users Everyone
      • Enable
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
        • Everyone
      • Suggest edit
        Permission
        Disabled Forbidden Owners Signed-in users Everyone
      • Enable
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
      • Emoji Reply
      • Enable
      • Versions and GitHub Sync
      • Note settings
      • Note Insights New
      • Engagement control
      • Make a copy
      • Transfer ownership
      • Delete this note
      • Insert from template
      • Import from
        • Dropbox
        • Google Drive
        • Gist
        • Clipboard
      • Export to
        • Dropbox
        • Google Drive
        • Gist
      • Download
        • Markdown
        • HTML
        • Raw HTML
    Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Help
    Menu
    Options
    Engagement control Make a copy Transfer ownership Delete this note
    Import from
    Dropbox Google Drive Gist Clipboard
    Export to
    Dropbox Google Drive Gist
    Download
    Markdown HTML Raw HTML
    Back
    Sharing URL Link copied
    /edit
    View mode
    • Edit mode
    • View mode
    • Book mode
    • Slide mode
    Edit mode View mode Book mode Slide mode
    Customize slides
    Note Permission
    Read
    Owners
    • Owners
    • Signed-in users
    • Everyone
    Owners Signed-in users Everyone
    Write
    Owners
    • Owners
    • Signed-in users
    • Everyone
    Owners Signed-in users Everyone
    Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Functional View ## Introduction Gradle's build behavior will vary with regards to the user's configuration. Gradle is engineered to provide each user the ability to configure it such that it exhibits the desired externally visible behavior. The functional view is focused on the functional capabilities of Gradle. Notably, its ability to build a software project. We believe that by narrowing the scope of our functional view to that of a Java project build specifically, we are able to better identify the architecturally significant components. Therefore, we have decided to use a Java project build as the scope of our functional view. Albeit not necessary for a succesful build, our scope includes the [Gradle daemon](#Gradle-Daemon) since it [improves performance significantly](https://docs.gradle.org/current/userguide/gradle_daemon.html#sec:why_the_daemon). Readers will notice that the functionality described in this view mostly pertains to Gradle's initialization and configuration. Since Gradle follows a [microkernel architectural style](https://hackmd.io/wlbMQxXaSmuTBk5hLWpKDQ#Microkernel-Architectural-Style), we focus our view not on the build behavior, but rather the systems which allow users to configure the build behavior. Exactly what is being built and executed is dictated by user-specific plugins and tasks, which we categorize as extended functionality. ## Table of Contents |Content|Description| |--|--| |[Gradle Build Lifecycle](#Gradle-Build-Lifecycle)| Introduces the inialization, configuration and execution phase of Gradle's build lifecycle.| |[Initialization Phase](#Initialization-Component-Diagram)| Showcases the functional components pertaining to the initialization phase. | |[Configuration](#Configuration-Component-Diagram)| Describes the components relating to the configuration phase.| |[Execution Phase](#Execution-System)| Gives a brief explanation of the execution system and explains why our AD does not go in much depth when describing the execution system. | |[Gradle Daemon](#Gradle-Daemon)| Details the Gradle Daemon, a lingering process used to improve build time.| |[Plugin Application Sequence Diagram](#Plugin-Application-Sequence-Diagram)| Details the sequence of events necessary for a plugin to be applied to a project.| ## Gradle Build Lifecycle To properly understand the way in which Gradle processes a build, it is important to understand the Gradle Build Lifecycle. * A build begins with the *Initialization phase*. In this phase, the command line arguments are parsed, the settings script file is found and parsed in order to find the locations of the projects to build. * A build then enters the *Configuratation phase*. In this phase, all the Gradle build files are loaded, and Projects are configured. Plugins are also applied in this step. Finally, Tasks are applied to a Project and a Task Directed Acyclic Graph (Task DAG) is created in order to keep track of dependencies between Tasks. * Finally, a build enters the *Execution phase*. In this phase, a Task execution tree is built according to task dependencies. The tasks are then executed. The build is complete after the execution phase. For more information [visit Gradle's website](https://docs.gradle.org/current/userguide/build_lifecycle.html). ### Initialization Component Diagram ![Initialization Component Diagram](https://i.imgur.com/ev7a5ZO.jpg) #### Initialization Element Catalog |Functional Component | Description | |--|--| |Launcher| The Launcher is Gradle's entry point. (relating to the [Entry Point](https://github.com/gradle/gradle/blob/master/subprojects/launcher/src/main/java/org/gradle/launcher/bootstrap/EntryPoint.java) class in the code). It is responsible for any initial bootstraping process, it then forwards any input arguments to the ActionManager which would use those arguments to initialize and execute a build. | |ActionManager| The ActionManager's responsibility is to build an action. It receives arguments and parses them (in the form of a [CommandLineExecution](https://github.com/gradle/gradle/blob/master/subprojects/launcher/src/main/java/org/gradle/launcher/bootstrap/CommandLineActionFactory.java)). It then initializes the build action and forwards the result to the Initializer. </br></br> The Initializer may run on the current process or on a seperate process depending on the input arguments. To run the Initializer on a seperate process, the ActionManager will instead forward the arguments to a DaemonClient.| |DeamonClient | The [DaemonClient's](https://github.com/gradle/gradle/blob/master/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/client/DaemonClient.java) main responsibility is to find a lingering Daemon and forward the build action to it. It creates a Daemon if it cannot find one.</br></br> More information on why it does this can be found in the [Gradle Daemon](#Gradle-Daemon) section. |Daemon | The [Daemon's](https://github.com/gradle/gradle/blob/master/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/server/Daemon.java) main responsibility is to receive build actions from the DaemonClient and to execute the action via a (process local) Initializer.| |Initializer | The Initializer's main responsibility is to coordinate the inialization phase of the Gradle Build Lifecycle. It first starts by loading the [settings script file](https://hackmd.io/pxTuGPrNQi2Am2p5z5U8Jw#settingsgradle) into a Settings [configuration object](https://hackmd.io/pxTuGPrNQi2Am2p5z5U8Jw#Configuration-Objects). </br></br> The initializer then launches the configuration phase by interfacing with configuration subsytem. The configuration phase requires a loaded Settings configuration object which contains valuable information such as which projects to build (therefore which Project configuration object to configure). </br></br>Once, the configuration phase is done, the Initializer launches the execution phase by interfacing with the Execution subsystem.| |Settings | [Settings](https://github.com/gradle/gradle/blob/master/subprojects/core-api/src/main/java/org/gradle/api/initialization/Settings.java) is a [configuration object](https://hackmd.io/pxTuGPrNQi2Am2p5z5U8Jw#Configuration-Objects). Its main responsibility is to locate and load the settings script file (into itself). This step includes identifying all the projects required for the build (dictated in the settings' script file).| #### Initialization Interfaces |Interface | Description | |--|--| |createAndRunBuildAction | This interface provides a way to parse the Launcher's input arguments and intialize a [BuildAction](https://github.com/gradle/gradle/blob/3a59747205706ef419fa41c1a4dbae0a3ea864a4/subprojects/core/src/main/java/org/gradle/internal/invocation/BuildAction.java#L23). A BuildAction simply simply represents a Gradle build to be performed. The BuildAction is created by an action factory, for example [DefaultCommandLineActionFactory](https://github.com/gradle/gradle/blob/049876d4dd8b0cc7615cf96b9b6d979ffb965be7/subprojects/launcher/src/main/java/org/gradle/launcher/cli/DefaultCommandLineActionFactory.java#L57). | |executeOnDaemon | This interfaces provides a way for the ActionManager to forward a BuildAction to the DaemonClient. The Daemon Client then finds a lingered Daemon process on which the BuildAction can be executed.| |executeBuildAction | This interface is provided by the Initializer and simply begins the execution of a BuildAction. The Initializer includes classes such as the [BuildActionExecuter](https://github.com/gradle/gradle/blob/master/subprojects/tooling-api/src/main/java/org/gradle/tooling/BuildActionExecuter.java). | |Message | The build action is sent between a DaemonClient and the Daemon through a [Message](https://github.com/gradle/gradle/blob/master/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/protocol/Message.java). The message is sent from the Client through a [DaemonClientConnection](https://github.com/gradle/gradle/blob/master/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/client/DaemonClientConnection.java). The message is received in a [DaemonConnection](https://github.com/gradle/gradle/blob/a7ed5ebdd4bbbcb02b7323e418acc0998abc27aa/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/server/api/DaemonConnection.java) | |findAndLoadSettings | Creates an instance of a Settings [configuration object](https://hackmd.io/pxTuGPrNQi2Am2p5z5U8Jw#Configuration-Objects). This is done via a [SettingsLoader](https://github.com/gradle/gradle/blob/a7ed5ebdd4bbbcb02b7323e418acc0998abc27aa/subprojects/core/src/main/java/org/gradle/initialization/SettingsLoader.java) which takes care of the loading of the [settings' script file](https://hackmd.io/pxTuGPrNQi2Am2p5z5U8Jw#settingsgradle) into the configuration object | |startExecution | Forwards the necessary information to the Execution System (projects, tasks, ...) and begins the final phase of the Gradle build lifecylce, the execution phase.| |createProjects | Loads the Project's [build.gradle file](https://hackmd.io/pxTuGPrNQi2Am2p5z5U8Jw#buildgradle) in to the project configuration object. Further initializes the project configuration object instance by resolving any missing artifact such as plugins. Applies the necessary plugins to the project.| ### Configuration Component Diagram ![Component Diagram](https://i.imgur.com/0RCRDEO.jpg) #### Configuration/Execution Element Catalog |Functional Component | Description | |--|--| |Task | The [Task](https://github.com/gradle/gradle/blob/master/subprojects/core-api/src/main/java/org/gradle/api/Task.java) component's main responsibility is to represent a "unit of work". A task contains an ordered list of runnable actions (much like a linked-list) and keeps track of the tasks it depends on (must be executed before). | |Project | A [Project](https://github.com/gradle/gradle/blob/master/subprojects/core-api/src/main/java/org/gradle/api/Project.java) [configuration object](https://hackmd.io/pxTuGPrNQi2Am2p5z5U8Jw#Configuration-Objects) is mapped to a [build.gradle file](https://hackmd.io/pxTuGPrNQi2Am2p5z5U8Jw#buildgradle). It may contain subprojects but there is only one root project. A Project contains tasks and may have plugins applied on it. It is the glue that connects most components together and it represents source code that must be built.| |Build Cache | In terms of functionalities the [BuildCache](https://hackmd.io/pxTuGPrNQi2Am2p5z5U8Jw#Build-Cache) handles the storing and retrieval of cached files (task outputs), it is explored in depth in the [information view](https://hackmd.io/pxTuGPrNQi2Am2p5z5U8Jw). | |Plugin | A [Plugin](https://github.com/gradle/gradle/blob/master/subprojects/core-api/src/main/java/org/gradle/api/Plugin.java) can be used to extend a project in many ways. The most common way is to add a (or multiple) tasks to a project. Plugins are specified in a [project's script file](https://hackmd.io/pxTuGPrNQi2Am2p5z5U8Jw#buildgradle). | |Artifact Repository | A repository contains artifacts that follow a specific format, for example "[artifact]-[version].[ext]". when a project's artifact repositories are missing an important artifact (such as a plugin), then the artifact must be fetched from a Source. | | Source | An abstract components which is used to model any entity that exposes a way to retrieve artifacts (such as files). The artifact repository will resolve missing artifacts from the source via the strategy design pattern. | #### Configuration & Execution Interfaces |Interface | Description | |--|--| | execute | Executes the task. The actual work done is done by [Actions](https://github.com/gradle/gradle/blob/a7ed5ebdd4bbbcb02b7323e418acc0998abc27aa/subprojects/base-services/src/main/java/org/gradle/api/Action.java). To execute a Task, the list of actions are retreived, and then executed in order. This work is wrapped in a [TaskExecution](https://github.com/gradle/gradle/blob/a7ed5ebdd4bbbcb02b7323e418acc0998abc27aa/subprojects/core/src/main/java/org/gradle/api/internal/tasks/execution/TaskExecution.java). This is called by the execution system. | | registerTask | A project contains tasks, therefore the registerTask interface is used to register a task to a project. | | configureProject | Represents the inversion of control, meaning that a Project gives an "instance" of itself to Plugin such that Plugin can configure the instance of Project (by addding tasks for example). | | getCachedOutput | Accesses a previously computed task output from the [BuildCache](https://hackmd.io/pxTuGPrNQi2Am2p5z5U8Jw#Build-Cache). | | applyPlugin | The Plugin component applies itself to a Project instance in order to given the plugin increased functionality through making the Project aware of available Tasks. The [PluginManager](https://github.com/gradle/gradle/blob/a7ed5ebdd4bbbcb02b7323e418acc0998abc27aa/subprojects/core-api/src/main/java/org/gradle/api/plugins/PluginManager.java) keeps track of which plugins have been applied. | | resolveArtifact | The artifact resolution uses the strategy design pattern to define a resolution protocol specific to a perticular Source. The resolution strategy should be such that artifacts are only fetched from a remote Source if they are not present locally. This is evidenced by the [FileResolver](https://github.com/gradle/gradle/blob/31be39c23e3d4c5d6ab3c043c189166d09ce3085/subprojects/file-collections/src/main/java/org/gradle/api/internal/file/FileResolver.java#L29). | | getArtifact | This is a conceptual interface which abstracts the way a source exposes artifacts to the ArtifactRepository. Since each Source may expose artifacts differently (e.g. via an HTTP web server), we will not go into details.| ### Execution System The execution system is architecturally simple and its complexity is present mostly at the software design level. Our AD, strives to be both clear and concise, therefore we will present a high-level overview of the execution system. Once the configuration phase is over the initialization system begins the execution phase. The execution system builds a task dependency tree and executes tasks in a correct order (with regards to the dependency tree). Since tasks can be seen as a linked-list of actions, the execution system further ensures that the actions of each task are executed in the correct order. ## Gradle Daemon Gradle strives to be very performant. It achieves this partly by utilizing a daemon process. Gradle's initialization is loosely coupled with the configuration and execution of the build, therefore running the build on a seperate process is as simple as delivering a BuildAction message to another process, the Gradle daemon. The Gradle daemon is a lingering background process which maintains the result of any previously executed build's bootstraping in memory. #### Performance The Gradle daemon can speed up [builds by 15-75%](https://docs.gradle.org/current/userguide/gradle_daemon.html#sec:why_the_daemon). The daemon allows redundant, yet expensive, bootstrapping operations to be skipped (e.g. loading of large libraries into memory) by keeping the preivious build's bootstrapping results in-memory. This performance does come with a cost, [alot of memory](https://java.tutorialink.com/high-memory-usage-by-gradle-daemon/) can be used by the Gradle daemon. However, due to [architectural princple #2](https://hackmd.io/fn2LiZ9VSba1y9bW7DXf5w#2), which dictates that build performance takes precedence over memory utilization, this is not a major issue. It is strongly discouraged to execute Gradle builds without the daemon since in most scenarios, the daemon does not consume much memory. ## Plugin Application Sequence Diagram ![Plugin Application Sequence Diagram](https://i.imgur.com/58eu4Bt.jpg) ### Description of Sequence Diagram One of our [important scenarios](https://hackmd.io/2sH_s1J1SeaK5QHdD8fL6w?view#Scenario-2-Applying-Plugins-to-increase-Gradle%E2%80%99s-Functionality) is the application of plugins to increase Gradle's functionality. Plugin application is not straight forward and unintuitive (evidenced by the inversion of control). Therefore, we believe that it is important to properly showcase the execution sequence which leads to a plugin being applied on a specific Project. We hope that this diagram helps readers understand that the plugin configures the project at run-time, after the initialization of Gradle. In the diagram, we notice that Project appears twice. In fact, readers will notice that the same instance "proj:Project" calls apply on Plugin and Plugin calls configure back on "proj:Project".

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Google Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully