Skip to main content
Back to Blog

Complete Java Setup Guide on macOS (Apple Silicon M Chips), Copy and Run for Beginners

2/22/2026

I recently moved from Windows to an M4 MacBook Air. In the AI era, macOS gives a better vibe-coding experience. This guide records my full Java environment setup process, and every command is copy-and-run.

Why move from Windows to Mac?

In AI-assisted development, many engineers are shifting from “typing every line” to “directing AI to implement.” This workflow needs:

  • Smooth terminal-first development
  • Better support for AI tools like Claude Code and Cursor
  • Higher consistency between local and server environments

After moving to Apple Silicon, common issues appeared quickly:

  • Why does JDK 8 fail to install?
  • Why does Maven report illegal instruction?
  • Why are dependency downloads so slow?
  • How do I manage multiple JDK versions for different projects?

The root cause is usually the same: architecture migration (x86_64 to arm64) plus platform migration (Windows to macOS).

The good news: with the right tooling, these issues are straightforward to solve.


Why Homebrew + SDKMAN?

Traditional setup pain points

Manual installer workflows still work on macOS, but they are not ideal:

  • Manual JAVA_HOME and PATH management
  • Error-prone version switching
  • Hard-to-clean leftovers after uninstalling

Homebrew can install Java, but SDK-level version management is less flexible than SDKMAN for daily Java work.

SDKMAN strengths

SDKMAN is built for side-by-side SDK management:

  • Install / switch / remove by command
  • Keep JDK 8, 17, and 21 in parallel
  • Pin versions per project
  • Manage Maven, Gradle, Kotlin, Scala, and more

Recommended pattern:

  • Homebrew for system package management
  • SDKMAN for Java ecosystem toolchains

Step 1: Install Homebrew

Apple Silicon default Homebrew path is /opt/homebrew (Intel is /usr/local).

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Add Homebrew to PATH:

echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"

Verify:

brew --version

Step 2: Install SDKMAN

curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk version

If sdk version prints successfully, SDKMAN is ready.


Step 3: Install multiple JDK versions

List candidates:

sdk list java

Useful distributions:

  • tem (Eclipse Temurin): stable and common in production
  • zulu (Azul Zulu): better practical support for JDK 8 on Apple Silicon
  • graalce: GraalVM community build

Install versions:

sdk install java 21.0.10-tem
sdk install java 17.0.18-tem
sdk install java 8.0.482-zulu

Set default JDK:

sdk default java 21.0.10-tem

Check current version:

sdk current java
java -version

Temporary switch for current shell:

sdk use java 8.0.482-zulu

Permanent switch:

sdk default java 17.0.18-tem

List installed JDKs:

ls -1 ~/.sdkman/candidates/java


Step 4: Install Maven

List Maven versions:

sdk list maven

Install stable 3.9.x:

sdk install maven 3.9.12
sdk default maven 3.9.12

Verify:

mvn -v


Step 5: Project-level auto switching with .sdkmanrc

Enable auto env:

sdk config

Change:

sdkman_auto_env=true

Create .sdkmanrc per project.

Legacy project (JDK 8):

cat > .sdkmanrc << 'EOF2'
java=8.0.482-zulu
maven=3.9.12
EOF2

Spring Boot 3 project (JDK 17):

cat > .sdkmanrc << 'EOF2'
java=17.0.18-tem
maven=3.9.12
EOF2

New project (JDK 21):

cat > .sdkmanrc << 'EOF2'
java=21.0.10-tem
maven=3.9.12
EOF2

Activate and verify:

sdk env

Step 6: Speed up Maven downloads (China mirror)

Create settings:

mkdir -p ~/.m2
nano ~/.m2/settings.xml

Use Aliyun mirror:

<settings>
  <mirrors>
    <mirror>
      <id>aliyun</id>
      <mirrorOf>central</mirrorOf>
      <name>Aliyun Central</name>
      <url>https://maven.aliyun.com/repository/central</url>
    </mirror>
  </mirrors>
</settings>

Verify mirror usage:

mvn -X clean compile

Check for output like:

Using mirror aliyun (https://maven.aliyun.com/repository/central) for central

Step 7: Optional local repository relocation

Edit ~/.m2/settings.xml and add:

<localRepository>/Users/gfish/dev/maven-repository</localRepository>

Full example:

<settings>
  <localRepository>/Users/gfish/dev/maven-repository</localRepository>
  <mirrors>
    <mirror>
      <id>aliyun</id>
      <mirrorOf>central</mirrorOf>
      <name>Aliyun Central</name>
      <url>https://maven.aliyun.com/repository/central</url>
    </mirror>
  </mirrors>
</settings>

Create target folder:

mkdir -p /Users/gfish/dev/maven-repository

(Optional) migrate old cache:

mv ~/.m2/repository/* /Users/gfish/dev/maven-repository/

Verify configured local repo path:

mvn help:evaluate -Dexpression=settings.localRepository -q -DforceStdout

Step 8: Quick validation checklist

brew --version
sdk version
sdk current java
sdk current maven
java -version
mvn -v
ls -1 ~/.sdkman/candidates/java
ls -1 ~/.sdkman/candidates/maven
mvn -X clean compile | grep aliyun
mvn help:evaluate -Dexpression=settings.localRepository -q -DforceStdout

If all checks pass, your Java environment is ready.


Troubleshooting

JDK 8 install failure

Symptom: sdk install java 8.x.x-tem fails.

Fix: use Zulu on Apple Silicon.

sdk install java 8.0.482-zulu

Maven illegal instruction

Cause: old Maven version (for example 3.3.x) is incompatible with Apple Silicon.

Fix:

sdk install maven 3.9.12

Mirror still slow

Check:

  1. Mirror URL is https://maven.aliyun.com/repository/central
  2. mirrorOf is central, not *
  3. mvn -X logs confirm Aliyun mirror is used

Too much manual JDK switching

Fix: enable sdkman_auto_env=true and use .sdkmanrc in each project.


Reference environment layout

~/
├── .sdkman/
│   └── candidates/
│       ├── java/
│       │   ├── 8.0.482-zulu
│       │   ├── 17.0.18-tem
│       │   ├── 21.0.10-tem
│       │   └── current -> 21.0.10-tem
│       └── maven/
│           ├── 3.9.12
│           └── current -> 3.9.12
├── .m2/
│   ├── settings.xml
│   └── repository/ (or custom path)
└── .zprofile (contains brew shellenv)

Project layout:

~/projects/my-spring-boot-app/
├── .sdkmanrc
├── pom.xml
└── src/

Why macOS is strong for vibe coding

  • Unix-first terminal workflow
  • Better native experience for mainstream AI coding tools
  • Stronger parity between local and production environments
  • Great remote development setup with iTerm2 + tmux

Summary

Spend 30 minutes once, save many hours later:

  • Fast and reliable JDK switching
  • Project-level environment isolation
  • Faster dependency downloads
  • Reproducible setup on any new machine

Further reading