gradlew


Overview

`gradlew` is a Unix shell script designed to serve as the Gradle startup launcher on Unix-like systems (Linux, macOS, Cygwin). It acts as a platform-independent wrapper around the Gradle build tool, facilitating the setup of the Java Virtual Machine (JVM) environment and invoking the Gradle Wrapper runtime. The script handles environment configuration, JVM options, classpath setup, OS-specific adaptations, and finally launches the Gradle Wrapper Java process.

The primary purpose of this script is to abstract the complexities involved in launching Gradle builds, ensuring that the correct JVM and dependencies are used regardless of the user's environment or operating system nuances.


Detailed Explanation

Variables


Functions

warn

warn ( ) {
    echo "$*"
}
warn "This is a warning message."

die

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}
die "Fatal error: JAVA_HOME not set correctly."

splitJvmOpts

function splitJvmOpts() {
    JVM_OPTS=("$@")
}

Implementation Details and Workflow

  1. OS Detection:
    The script detects whether it is running on Cygwin, MSYS, or Darwin (macOS) environments by parsing the output of uname. This information guides path handling and OS-specific JVM options.

  2. Resolving Script Location:
    The script resolves any symbolic links pointing to the script to determine the true script location. This enables setting APP_HOME reliably to the root directory of the Gradle installation.

  3. Classpath Setup:
    The classpath is set to the Gradle Wrapper jar (gradle-wrapper.jar) inside the gradle/wrapper directory relative to APP_HOME.

  4. Java Executable Determination:
    The script checks for a valid JAVA_HOME environment variable and verifies the existence and executability of the Java binary inside it. If missing or invalid, it attempts to use java from the system PATH. If no valid Java executable is found, it terminates with an error.

  5. Max File Descriptor Limit:
    On non-Cygwin and non-Darwin systems, it attempts to increase the maximum number of file descriptors to the system maximum or a user-defined value. This improves Gradle's ability to open many files simultaneously during builds.

  6. macOS Dock Integration:
    On Darwin, additional JVM options are appended to set the application name and icon for the macOS dock.

  7. Cygwin Path Conversion:
    For Cygwin environments, the script converts POSIX paths to Windows paths for APP_HOME, CLASSPATH, and JAVACMD to ensure compatibility with Windows JVMs and Gradle.

    It also processes command line arguments to convert them as appropriate, skipping options starting with -.

  8. JVM Options Assembly:
    JVM options are gathered from DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables, parsed via splitJvmOpts into an array. Additionally, a system property is added to identify the Gradle app name.

  9. Execution:
    The script finally uses exec to replace the shell process with the java process, launching the Java class org.gradle.wrapper.GradleWrapperMain with the assembled JVM options and all original script arguments.


Usage Example

To use the Gradle Wrapper on a Unix-like system:

./gradlew build

This will:


Interaction with Other System Components


Visual Diagram

The following flowchart illustrates the main flow and decision points within the `gradlew` script:

flowchart TD
    Start[Start Script] --> DetectOS{Detect OS Environment}
    DetectOS -->|Cygwin| SetCygwinTrue[Set cygwin=true]
    DetectOS -->|Darwin| SetDarwinTrue[Set darwin=true]
    DetectOS -->|MSYS| SetMsysTrue[Set msys=true]
    DetectOS -->|Others| NoFlag[No OS Flag]

    SetCygwinTrue --> ResolveLinks
    SetDarwinTrue --> ResolveLinks
    SetMsysTrue --> ResolveLinks
    NoFlag --> ResolveLinks

    ResolveLinks[Resolve Script Symlinks] --> SetAppHome[Set APP_HOME]

    SetAppHome --> SetClasspath[Set CLASSPATH to gradle-wrapper.jar]

    SetClasspath --> DetermineJavaCmd{JAVA_HOME set?}
    DetermineJavaCmd -->|Yes| CheckJavaExec[Check JAVA_HOME/java executable]
    DetermineJavaCmd -->|No| UseSystemJava[Use 'java' from PATH]

    CheckJavaExec -->|Executable| JavaCmdReady[Set JAVACMD]
    CheckJavaExec -->|Not Executable| DieError[Exit with error]

    UseSystemJava --> CheckJavaInPath{Is 'java' in PATH?}
    CheckJavaInPath -->|Yes| JavaCmdReady
    CheckJavaInPath -->|No| DieError

    JavaCmdReady --> IncreaseFDLimit{Not cygwin or darwin?}
    IncreaseFDLimit -->|Yes| TryIncreaseFD[Attempt ulimit -n]
    IncreaseFDLimit -->|No| SkipFDLimit[Skip]

    TryIncreaseFD --> WarnOnFail[Warn if fails] --> SetupDarwinOptions
    SkipFDLimit --> SetupDarwinOptions

    SetupDarwinOptions{Is darwin?} -->|Yes| AddDockOptions
    SetupDarwinOptions -->|No| SetupCygwinPaths

    AddDockOptions --> SetupCygwinPaths

    SetupCygwinPaths{Is cygwin?} -->|Yes| ConvertPathsAndArgs
    SetupCygwinPaths -->|No| PrepareJvmOpts

    ConvertPathsAndArgs --> PrepareJvmOpts

    PrepareJvmOpts[Split JVM_OPTS from DEFAULT_JVM_OPTS, JAVA_OPTS, GRADLE_OPTS] --> AddAppNameProperty

    AddAppNameProperty[Add -Dorg.gradle.appname property] --> ExecJava

    ExecJava[Execute Java command:\njava ${JVM_OPTS} -classpath CLASSPATH org.gradle.wrapper.GradleWrapperMain args] --> End[End]

Summary

The `gradlew` Unix shell script is an essential bootstrapper for Gradle builds, responsible for:

It enables users to run Gradle builds reliably without manual setup of Gradle distributions or complex environment configurations, supporting seamless and reproducible build environments across different Unix-like platforms.