macOS terminal notes — troubleshooting for CS1 students
This page is written for brand-new CS1 students. It groups common problems by scenario (what you see), explains in plain language what the computer is doing and why the fix works, gives exact copy/paste commands, and tells you how to check the fix worked. Every troubleshooting tip includes at least one authoritative link.
Quick glossary (short, plain language)
- PATH: A list of folders your shell checks when you type a command like
java. If the program’s folder isn’t in PATH, the shell says “command not found.” (More: https://www.gnu.org/software/bash/manual/html_node/The-Path.html) - JAVA_HOME: A variable that points to where Java (the JDK) is installed. Some tools (including parts of Gradle) use this to find the Java executables.
- JDK vs JRE: JDK = Java Development Kit (you need this to compile with
javac). JRE only runs programs. - Gradle wrapper (
gradlew/gradlew.bat): a tiny script included in each assignment that downloads and runs the project’s Gradle version (course uses Gradle 9.2.0). Using the wrapper ensures everyone runs the same Gradle. (Official: https://docs.gradle.org/current/userguide/gradle_wrapper.html) - Terminal vs Shell: “Terminal” is the window or app; the “shell” (zsh, bash) is the program that reads your typed commands.
Important course versions (please remember these)
- Java: JDK 25 (Eclipse Temurin by Adoptium). See /setup/setup-jdk/ for official instructions and downloads.
- Gradle: Use the project wrapper — our assignments use Gradle 9.2.0 (the wrapper downloads it for you).
Scenario A — “java: command not found” or the wrong Java version shows up
What you see
java --versionprints “command not found” or printsopenjdk 17(or another older/newer version) instead ofopenjdk 25.
Plain-language explanation
- You either don’t have JDK 25 installed, or the shell you opened doesn’t know where the JDK is (PATH or JAVA_HOME aren’t set for that shell). Gradle needs the JDK to compile and run tests.
Diagnostics (copy-paste these and paste the results into Discord if you need help)
which java
java --version
javac --version
echo $JAVA_HOME
Fix — install or point to JDK 25
- If Java is not installed, install Temurin 25 (Adoptium). Homebrew users:
brew install --cask temurin@25
-
Or download the macOS .pkg from Adoptium and run the installer: https://adoptium.net/
-
If Java is installed but the wrong version is first in PATH, set JAVA_HOME to JDK 25 and put it first in PATH (put this in ~/.zprofile so GUI apps like VS Code see it):
# ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)" # only if you use Homebrew
export JAVA_HOME="$([ -x /usr/libexec/java_home ] && /usr/libexec/java_home -v 25)"
export PATH="$JAVA_HOME/bin:$PATH"
Then restart VS Code entirely (quit and reopen) or run source ~/.zprofile in your terminal and re-open VS Code with code ..
How to tell it worked
java --versionshows Temurin 25 (for example:openjdk 25 ... Temurin-25...).javac --versionprintsjavac 25.
Authoritative links
- Adoptium (Temurin): https://adoptium.net/
- macOS
java_homehelper: built-in man pageman java_homeand Apple docs.
Scenario B — “Permission denied” when running ./gradlew (or weird “bad interpreter” errors)
What you see
- Running
./gradlew testprintsPermission deniedor an error like/usr/bin/env: 'bash\r': No such file or directory.
Plain-language explanation
- The wrapper file needs the executable bit set (on Unix systems) and it must use Unix line endings (LF). If the file has Windows line endings (CRLF) the shell sees an extra
\rcharacter and fails.
Diagnostics
ls -l gradlew
file gradlew
head -n 1 gradlew | sed -n '1p' # shows shebang line
Fixes (what they do)
- Make the wrapper executable:
chmod +x gradlew
./gradlew --version
- If you see the
bash\rtype error, convert line endings to Unix style (LF):
brew install dos2unix || true
dos2unix gradlew
chmod +x gradlew
How to tell it worked
ls -l gradlewshowsxbits (example:-rwxr-xr-x)../gradlew --versionprints wrapper and Gradle info (wrapper will download Gradle on first run). No more bad-interpreter errors.
Authoritative links
- Gradle wrapper docs: https://docs.gradle.org/current/userguide/gradle_wrapper.html
- Newline/line endings explanation: https://en.wikipedia.org/wiki/Newline
Scenario C — VS Code terminal doesn’t see Java but Terminal.app does
What you see
java --versionshows JDK 25 in Terminal.app but inside VS Code’s integrated terminal the command is missing or shows a different version.
Plain-language explanation
- GUI apps launched from the Dock/Spotlight can get a different environment than shells launched from Terminal.app. Some shell files (like ~/.zshrc) are only read for interactive shells; GUI apps may read ~/.zprofile (login shells). The result: VS Code may not inherit PATH/JAVA_HOME you set in some files.
Fix — two safe options
1) Start VS Code from the terminal so it inherits your shell environment:
cd /path/to/your/project
code .
2) Put persistent environment exports in ~/.zprofile (GUI apps are more likely to pick that up):
# add to ~/.zprofile
export JAVA_HOME="$([ -x /usr/libexec/java_home ] && /usr/libexec/java_home -v 25)"
export PATH="$JAVA_HOME/bin:$PATH"
How to tell it worked
- After restarting VS Code (fully quit and reopen), run
java --versionin the integrated terminal — it should match Terminal.app and show Temurin 25.
Authoritative link
- VS Code docs: https://code.visualstudio.com/docs/editor/integrated-terminal
Scenario D — “First run is slow/Gradle downloads hang”
What you see
./gradlew testshows downloading messages and takes a long time or stalls.
Plain-language explanation
- The Gradle wrapper downloads a specific Gradle distribution and the project’s dependencies into
~/.gradle. This only happens the first time and can be tens or hundreds of MB.
What to check
./gradlew test --info
df -h ~
ls -la ~/.gradle/wrapper/dists || true
du -sh ~/.gradle || true
What to do
- Be patient on the first run. If you’re behind a corporate proxy, add proxy settings in
~/.gradle/gradle.properties(Gradle docs explain the format). - If you are low on disk, move the Gradle cache to a larger location and symlink it (example below).
How to move Gradle cache (example — advanced; back up first)
# copy caches to new location, then symlink
mkdir -p /path/to/big/storage/gradle-cache
rsync -a ~/.gradle/ /path/to/big/storage/gradle-cache/
mv ~/.gradle ~/.gradle.old && ln -s /path/to/big/storage/gradle-cache ~/.gradle
# test by running ./gradlew test; if all good, remove ~/.gradle.old
Authoritative link
- Gradle wrapper docs: https://docs.gradle.org/current/userguide/gradle_wrapper.html
Scenario E — permission errors after using sudo
What you see
- Gradle can’t write into
~/.gradleor the project’sbuild/directory and errors mention permission denied.
Plain-language explanation
- Running commands with
sudomay create files owned by root in your home directory. Your normal user can’t overwrite them.
Fix (recover safely)
sudo chown -R $(whoami) ~/.gradle
sudo chown -R $(whoami) /path/to/your/project/.gradle /path/to/your/project/build || true
./gradlew clean build
How to tell it worked
ls -ld ~/.gradleshows your username as owner../gradlew clean buildruns without permission errors.
Scenario F — pasted text shows strange characters (bracketed paste issues)
What you see
- Pasting into the terminal inserts odd sequences like
1~or^Minstead of the pasted text.
Why it happens
- Terminals use “bracketed paste mode” to support safe multi-line paste. If the shell/terminal mismatch, pastes can be misinterpreted.
Fixes
# temporarily disable bracketed paste for the current terminal session
printf "\e[?2004l"
# or in VS Code settings.json (user settings)
"terminal.integrated.ignoreBracketedPasteMode": true
How to tell
- After the change, paste
echo hello— you should seeecho helloand not stray characters; running it printshello.
Scenario G — which Gradle command do I run?
Short answer
- Use the project wrapper:
./gradlew test(macOS/Linux) orgradlew.bat test(Windows). The wrapper makes sure everyone uses the same Gradle (our assignments use 9.2.0).
How to verify you used the wrapper
./gradlew --version
The output will report the Gradle version (expect 9.2.0 for course repos). If it reports another version, you are probably running a system gradle instead of the wrapper.
Final quick checklist for macOS (step-by-step, designed for a new CS1 student)
- Open VS Code and the integrated terminal (Control + `).
- Run:
java --version— you should see Temurin 25. If not, install Temurin 25 (https://adoptium.net/) or use Homebrewbrew install --cask temurin@25. - In your assignment folder run:
./gradlew --version— it should show Gradle 9.2.0. - Run:
./gradlew testand allow the first-run downloads to complete.
If you hit an error, find the scenario that matches the error text above and follow the step-by-step fix. When in doubt, copy the exact error and post it on the course Discord along with the commands you ran and the outputs of java --version and ./gradlew --version.
Authoritative references (quick)
- Adoptium (Temurin JDK 25): https://adoptium.net/
- Gradle wrapper docs: https://docs.gradle.org/current/userguide/gradle_wrapper.html
- VS Code integrated terminal docs: https://code.visualstudio.com/docs/editor/integrated-terminal
- Homebrew docs: https://docs.brew.sh/Installation
- Newline/line ending explanation: https://en.wikipedia.org/wiki/Newline
If this looks good I will apply the same student-friendly, scenario-based restructuring to the Windows, Linux, and Chromebook notes pages.