skip to content

Which wrapper files belong in version control, and what practical pitfalls (line endings, executable bit, .gitignore) trip teams up?

level: seniorimportance: should knowfreq 45%

answer

  1. commit all four
  2. *.jar / gradle/ ignore drops the jar
  3. GradleWrapperMain not found
  4. git update-index --chmod=+x gradlew
  5. .gitattributes eol=lf for gradlew

basics

~10 s

Commit all four wrapper files (gradlew, gradlew.bat, gradle-wrapper.jar, gradle-wrapper.properties). Pitfalls: accidentally gitignoring the jar, losing gradlew's executable bit, and CRLF line endings breaking the Unix script.

solid answer

~50 s

All four wrapper files must be committed: `gradlew`, `gradlew.bat`, and both files under `gradle/wrapper/`. Together they let a JDK-only clone build reproducibly, so excluding any of them defeats the purpose. Common real-world pitfalls: - **Over-broad .gitignore** — patterns like `*.jar` or a blanket `gradle/` rule can silently drop `gradle-wrapper.jar`; CI then fails with 'Could not find or load main class org.gradle.wrapper.GradleWrapperMain'. Force-add it (`git add -f`). - **Lost executable bit** — `gradlew` needs its executable permission; if it's checked in without it, Unix/CI users get 'Permission denied'. Fix with `git update-index --chmod=+x gradlew`. - **Line endings** — if `gradlew` is committed or checked out with CRLF, the shell fails with a `bad interpreter` error. Pin it via `.gitattributes` (`gradlew text eol=lf`). A `.gitattributes` plus verifying the jar and exec bit are tracked is the standard prevention.

code

bash · 9 lines
bash
# Force-track the jar if an ignore rule hid it
git add -f gradle/wrapper/gradle-wrapper.jar

# Restore the executable bit on the Unix launcher
git update-index --chmod=+x gradlew

# .gitattributes to keep line endings sane
#   gradlew text eol=lf
#   *.bat   text eol=crlf

go deeper

for a junior

Know that all four files are committed and you shouldn't gitignore the jar.

for a middle

List the three pitfalls and recognize the missing-jar error message.

for a senior

Give the concrete fixes (git add -f, update-index --chmod, .gitattributes) and explain why each happens.

for a principal

Bake these guards into repo templates/linters so every new project is wrapper-correct by default across the org.

## What must be committed All **four** wrapper files are part of the source tree and must be tracked: ``` gradlew gradlew.bat gradle/wrapper/gradle-wrapper.jar gradle/wrapper/gradle-wrapper.properties ``` The entire value proposition — clone with only a JDK and build the exact pinned Gradle — collapses if any is missing. ## Pitfall 1 — accidental .gitignore exclusion A broad ignore rule is the classic foot-gun: ```gitignore # DANGER: these can drop the wrapper jar *.jar gradle/ ``` When `gradle-wrapper.jar` is missing, the scripts run but the JVM can't find the bootstrap class: ``` Error: Could not find or load main class org.gradle.wrapper.GradleWrapperMain ``` Fix by force-adding and tightening the ignore rules: ```bash git add -f gradle/wrapper/gradle-wrapper.jar ``` Prefer narrow ignores (e.g. `build/`, `.gradle/`) over `*.jar`. ## Pitfall 2 — the executable bit on gradlew On Unix, `gradlew` must be executable. If it was added on Windows or had its mode stripped, Linux/macOS and CI users hit: ``` bash: ./gradlew: Permission denied ``` Restore the tracked permission without touching content: ```bash git update-index --chmod=+x gradlew git commit -m "Mark gradlew executable" ``` ## Pitfall 3 — line endings `gradlew` is a POSIX shell script. If Git (or an editor) rewrites it to CRLF, the shebang line is corrupted and you get: ``` ./gradlew: /bin/sh^M: bad interpreter: No such file or directory ``` Guard it with `.gitattributes` so the Unix script is always LF and the batch file is CRLF: ```gitattributes * text=auto gradlew text eol=lf *.bat text eol=crlf ``` ## Putting it together The robust setup is: commit all four files, add a `.gitattributes`, verify the jar is tracked (`git ls-files | grep wrapper`), and confirm `gradlew` carries its executable bit. These three habits eliminate the overwhelming majority of 'wrapper works for me but not on CI' incidents. ## Note on integrity Verifying the *authenticity* of the jar (checksums) is a separate, deeper concern; here the focus is simply making sure the correct files are present, executable, and uncorrupted in version control.

  • CI fails with 'Could not find or load main class org.gradle.wrapper.GradleWrapperMain'. What is the first thing to check?
    Whether gradle-wrapper.jar was actually committed — a broad .gitignore (e.g. *.jar) often drops it. Run git ls-files to confirm, and git add -f the jar.
  • Why pin gradlew's line endings to LF via .gitattributes?
    It is a POSIX shell script; CRLF corrupts the shebang and yields a 'bad interpreter' error on Unix. eol=lf keeps it runnable everywhere.
  • How do you fix a 'Permission denied' on ./gradlew that exists in the repo?
    Set the tracked executable bit with git update-index --chmod=+x gradlew and commit, so all clones get an executable script.

saying these in an interview costs you the question

  • Saying gradle-wrapper.jar should be gitignored because it's a binary.
  • Ignoring the executable bit, causing cross-platform 'Permission denied'.
  • Letting an editor save gradlew with CRLF and not guarding it.

context