맥에서 자바 버전 자유롭게 넘나들기

macOS에서 자바 개발을 시작하는 여정은 종종 'JAVA_HOME'이라는 보이지 않는 벽 앞에서 좌절감으로 시작되곤 합니다. 빌드가 이유 없이 실패하고, 로컬 서버는 꿈쩍도 하지 않으며, 애써 설치한 최신 IDE는 JDK를 찾지 못해 방황하는 상황. 인터넷을 헤매며 찾아낸 수많은 가이드는 단편적인 명령어 조각들만 던져줄 뿐, 왜 그 명령어를 실행해야 하는지, 내 Mac의 어떤 부분이 바뀌는지는 알려주지 않아 불안감만 키웁니다. 특히 Apple Silicon(M1, M2, M3)과 Intel 아키텍처가 공존하는 지금, 상황은 더욱 복잡해졌습니다.

이 글은 더 이상 여러분이 JAVA_HOME 설정 문제로 귀중한 개발 시간을 허비하지 않도록 돕기 위해 작성되었습니다. 저는 풀스택 개발자로서 수많은 프로젝트 환경을 설정하며 겪었던 시행착오와 해결책을 집대성했습니다. 단순히 '복사해서 붙여넣기' 수준을 넘어, JAVA_HOME이 자바 생태계의 핵심인지, macOS는 내부적으로 자바를 어떻게 인식하고 관리하는지, 그리고 최신 Apple Silicon과 Intel Mac 모두에서 완벽하게 동작하는 가장 표준적이고 현대적인 설정 방법은 무엇인지를 원리부터 실전까지 상세하게 파헤칩니다. 나아가 여러 버전의 자바를 프로젝트에 따라 마법처럼 전환하며 사용하는 전문가 수준의 팁과 자동화 도구 활용법까지 남김없이 담았습니다. 이 글을 끝까지 정독하고 나면, JAVA_HOME은 더 이상 당신의 발목을 잡는 장애물이 아닌, 개발 환경을 완벽하게 지배하는 강력한 무기가 될 것입니다.

1. 모든 것의 시작: JAVA_HOME, 대체 정체가 무엇일까?

JAVA_HOME은 시스템에 설치된 JDK(Java Development Kit)의 최상위 디렉토리 경로를 가리키는 환경 변수(Environment Variable)입니다. 운영체제나 다른 프로그램에게 "여기에 가면 자바 컴파일러, 실행기, 각종 개발 도구와 라이브러리가 모두 모여있다"고 알려주는, 말 그대로 '자바 개발의 총본산 주소' 역할을 합니다. 이것이 없다면 수많은 개발 도구들이 길 잃은 양처럼 헤매게 됩니다.

JRE와 JDK의 명확한 구분, JAVA_HOME의 존재 이유

자바 환경을 논할 때 JRE와 JDK라는 두 용어는 빠짐없이 등장합니다. 이 둘의 차이를 정확히 아는 것이 JAVA_HOME 설정의 첫 단추를 꿰는 일입니다.

  • JRE (Java Runtime Environment): '자바 실행 환경'입니다. 이미 컴파일된 자바 애플리케이션(.class, .jar 파일)을 실행하는 데 필요한 모든 것을 담고 있습니다. 핵심 요소는 자바 가상 머신(JVM)과 표준 라이브러리입니다. 즉, 개발자가 아닌 일반 사용자가 자바 기반 프로그램을 실행하기 위해 필요한 최소한의 패키지입니다.
  • JDK (Java Development Kit): '자바 개발 키트'로, JRE가 제공하는 모든 실행 환경을 포함하면서 추가로 개발에 필요한 도구들을 제공합니다. 가장 중요한 도구가 바로 우리가 작성한 소스 코드(.java 파일)를 JVM이 이해할 수 있는 바이트코드로 변환하는 자바 컴파일러(javac)입니다. 이 외에도 디버깅 도구(jdb), 문서 생성 도구(javadoc), 압축 도구(jar) 등이 모두 JDK에 포함됩니다.
핵심 정리: JAVA_HOME은 반드시 JRE가 아닌 JDK의 경로를 가리켜야 합니다. 빌드 도구나 IDE는 단순히 자바를 실행하는 것을 넘어, 코드를 컴파일하고 패키징하는 과정이 필수적이므로 javac와 같은 JDK에만 포함된 실행 파일을 명시적으로 찾아야 하기 때문입니다.

아래 표는 JDK와 JRE의 구조적 차이를 보여줍니다. JAVA_HOME이 왜 JDK의 최상위 디렉토리를 가리켜야 하는지 명확히 이해할 수 있습니다.

디렉토리/파일 JDK (Java Development Kit) JRE (Java Runtime Environment) 설명
bin/ 존재 (javac, jar, javadoc 등 포함) 존재 (java, keytool 등 일부만 포함) 실행 파일들이 위치하는 디렉토리. JAVA_HOME의 핵심입니다.
lib/ 존재 (tools.jar 등 개발 도구 라이브러리) 존재 (rt.jar 등 실행에 필요한 라이브러리) 개발 및 실행에 필요한 라이브러리 파일들.
include/ 존재 (JNI 헤더 파일) 없음 C/C++과 같은 네이티브 코드와 연동할 때 필요한 헤더 파일.
jre/ 포함 (이전 버전) / 통합 (최신 버전) N/A (자신이 JRE) JDK는 내부에 JRE를 포함하는 상위 집합입니다.

JAVA_HOME에 목마른 자바 생태계의 도구들

만약 JAVA_HOME이 제대로 설정되어 있지 않다면 어떻게 될까요? 자바 생태계를 지탱하는 거의 모든 주요 도구들이 올바르게 동작하지 않거나, 예상치 못한 버전의 자바를 사용하여 혼란을 야기할 수 있습니다. JAVA_HOME은 이들 사이의 표준화된 약속과도 같습니다.

  • 빌드 도구 (Maven, Gradle): mvn clean install 또는 ./gradlew build 명령을 실행할 때, 이 도구들은 가장 먼저 JAVA_HOME을 확인하여 프로젝트를 어떤 버전의 JDK로 컴파일할지 결정합니다. 설정이 없다면 시스템의 기본 자바를 사용하려 시도하지만, 이는 종종 의도치 않은 결과를 낳습니다.
  • CI/CD 서버 (Jenkins, GitLab CI): 젠킨스 에이전트나 GitLab Runner는 빌드 작업을 수행할 때마다 JAVA_HOME을 통해 JDK의 위치를 파악하고 빌드 환경을 구성합니다. 이 값이 없으면 빌드 잡(Job) 자체가 실패합니다.
  • 애플리케이션 서버 (Tomcat, WildFly): 톰캣의 startup.sh 스크립트를 실행하면, 스크립트 내부에서 JAVA_HOME 또는 JRE_HOME 변수를 찾아 서버를 구동할 자바 버전을 결정합니다.
  • 통합 개발 환경 (IDE - IntelliJ, Eclipse, VS Code): IDE는 새로운 프로젝트를 생성하거나 기존 프로젝트를 불러올 때, 시스템에 설정된 JAVA_HOME을 기본 JDK로 제안합니다. 물론 IDE 내부에서 프로젝트별로 다른 JDK를 설정할 수 있지만, 초기 설정의 기준점이 됩니다.
  • 빅데이터 프레임워크 (Hadoop, Spark): 자바 기반의 거의 모든 빅데이터 솔루션들은 실행 환경을 구성하고 데몬(Daemon) 프로세스를 띄울 때 JAVA_HOME을 필수적으로 요구합니다.

여러 자바 버전을 지배하는 열쇠

현대의 풀스택 개발 환경에서 단 하나의 자바 버전만 사용하는 경우는 거의 없습니다. 안정성이 중요한 운영 서버의 레거시 시스템은 자바 8이나 11로 유지보수해야 하고, 새로운 마이크로서비스는 최신 LTS(Long-Term Support) 버전인 자바 17이나 21의 새로운 기능과 성능 향상을 활용하여 개발해야 합니다. 이때 JAVA_HOME 변수의 값을 변경하는 것만으로 터미널 세션이나 특정 프로젝트에서 사용할 기본 자바 버전을 손쉽게 전환할 수 있습니다. 이것이 바로 JAVA_HOME이 단순한 경로 설정을 넘어, 자바 버전 관리의 핵심 전략이 되는 이유입니다.

2. 내 Mac의 자바 현황 파악: 가장 확실하고 유일한 방법

JAVA_HOME을 설정하려면, 먼저 내 컴퓨터에 어떤 버전의 자바가 어디에 설치되어 있는지 정확히 파악해야 합니다. 많은 개발자들이 /Library/Java/JavaVirtualMachines 디렉토리를 직접 `ls` 명령어로 확인하곤 하지만, macOS는 이보다 훨씬 더 스마트하고 표준적인 방법을 제공합니다. 바로 /usr/libexec/java_home 이라는 강력한 유틸리티입니다.

macOS의 공식 자바 관리자, `/usr/libexec/java_home`

이 유틸리티는 macOS가 시스템에 설치된 모든 JDK를 추적하고 관리하기 위해 사용하는 공식 도구입니다. Spotlight 인덱싱과 연동하여 시스템 전역(/Library/...) 또는 사용자 홈(~/Library/...)에 설치된 모든 JDK를 인식합니다. 이 명령어를 사용하면 하드코딩된 경로를 외우거나 찾을 필요 없이, 항상 정확하고 현재 활성화된 JDK 경로를 동적으로 얻을 수 있습니다. 터미널(Terminal) 앱을 열고 다음 명령어들을 실행해보세요.

모든 설치된 JDK 버전과 경로 목록 확인 (가장 중요!)

이 명령어 하나면 당신의 Mac에 설치된 모든 JDK 현황을 한눈에 파악할 수 있습니다. 이 명령어를 가장 먼저 실행하는 습관을 들이는 것이 좋습니다.

/usr/libexec/java_home -V

이 명령을 실행하면 사용자 환경에 따라 다음과 비슷한 결과가 출력됩니다.

Matching Java Virtual Machines (4):
    21.0.1 (arm64) "Oracle Corporation" - "Java SE 21.0.1" /Library/Java/JavaVirtualMachines/jdk-21.0.1.jdk/Contents/Home
    17.0.8 (arm64) "Amazon.com Inc." - "Amazon Corretto 17" /Users/myuser/Library/Java/JavaVirtualMachines/corretto-17.0.8/Contents/Home
    11.0.20 (x86_64) "Azul Systems, Inc." - "Zulu 11.66.19" /Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home
    1.8.0_382 (arm64) "Eclipse Temurin" - "Eclipse Temurin 8" /Library/Java/JavaVirtualMachines/temurin-8.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/jdk-21.0.1.jdk/Contents/Home

이 출력 결과는 단순한 목록이 아닌, 보물 지도와 같습니다. 각 부분을 자세히 분석해 봅시다.

  • 개수 및 버전: 현재 시스템에 총 4개의 JDK(21.0.1, 17.0.8, 11.0.20, 1.8)가 설치되어 있음을 알려줍니다.
  • 아키텍처: (arm64)는 Apple Silicon(M1/M2/M3) 네이티브 버전을, (x86_64)는 Intel 버전을 의미합니다. Apple Silicon Mac에서는 Rosetta 2 호환성 레이어를 통해 Intel 버전도 실행 가능하지만, 성능상 arm64 버전 사용이 압도적으로 유리합니다.
  • 제공사(Vendor): 어떤 배포판의 JDK인지 명확히 보여줍니다. "Oracle", "Amazon Corretto", "Azul Zulu", "Eclipse Temurin" 등 다양한 배포판이 존재하며, 라이선스 정책과 지원 범위가 다릅니다.
  • 경로: 각 JDK가 설치된 실제 디렉토리 경로입니다. JAVA_HOME으로 설정해야 할 바로 그 값입니다.
  • 기본값(Default): 맨 마지막 줄에 별도로 출력되는 /Library/Java/JavaVirtualMachines/jdk-21.0.1.jdk/Contents/Home 경로는 현재 시스템이 '기본'으로 인식하는, 즉 가장 높은 버전 우선순위를 가진 JDK의 경로입니다.

현재 기본 JDK 경로만 깔끔하게 확인하기

단순히 기본 JDK의 경로만 알고 싶다면 -V 옵션 없이 실행합니다.

/usr/libexec/java_home

출력 결과:

/Library/Java/JavaVirtualMachines/jdk-21.0.1.jdk/Contents/Home

이 경로가 바로 우리가 JAVA_HOME으로 설정할 값입니다. 하지만 잠시 후 설명할 방법처럼, 이 경로를 직접 복사해서 하드코딩하는 것보다 이 명령어 자체를 동적으로 활용하는 것이 100배 더 현명하고 유지보수에 유리합니다.

3. 실전: 셸(Shell) 환경에 JAVA_HOME 영구적으로 각인시키기

이제 확인된 경로를 시스템이 항상 인식할 수 있도록 셸 설정 파일에 등록해야 합니다. 이 설정을 통해 터미널을 새로 열 때마다, 혹은 새로운 터미널 탭을 만들 때마다 JAVA_HOME이 자동으로 설정되어 일관된 개발 환경을 유지할 수 있습니다. macOS는 버전에 따라 기본 셸이 다르므로, 먼저 본인이 어떤 셸을 사용하는지 확인하는 것이 첫 단계입니다.

Step 1: 현재 사용 중인 셸(Shell) 확인

터미널에 다음 명령어를 입력하여 현재 어떤 셸을 사용하고 있는지 확인합니다.

echo $SHELL
  • 결과가 /bin/zsh 이면 Zsh 셸을 사용 중입니다. (macOS Catalina 및 이후 버전의 기본값)
  • 결과가 /bin/bash 이면 Bash 셸을 사용 중입니다. (macOS Mojave 및 이전 버전의 기본값 또는 사용자가 직접 변경한 경우)

자신의 셸 환경에 맞는 아래의 방법을 정확히 따르세요. 과정은 거의 동일하며 설정 파일의 이름만 다릅니다.

Step 2-A: Zsh 사용자를 위한 완벽 설정 (~/.zshrc 파일 수정)

Zsh 셸은 새로운 터미널 세션이 시작될 때마다 사용자의 홈 디렉토리(~)에 있는 .zshrc 파일의 설정을 읽어들여 환경을 구성합니다. (~/Users/사용자이름의 단축 표현입니다.)

  1. .zshrc 파일 열기
    선호하는 텍스트 편집기로 파일을 엽니다. 파일이 존재하지 않는다면 이 명령을 실행하는 순간 새로 생성되므로 걱정할 필요가 없습니다. 가장 간단한 내장 편집기인 nano를 사용해 보겠습니다.
    nano ~/.zshrc

    전문가 팁: 터미널 기반 편집기에 익숙하다면 vim ~/.zshrc를, GUI 기반 편집기를 선호한다면 VS Code에서 code ~/.zshrc 명령 (VS Code 'code' command in PATH 설치 필요)을 사용하는 것이 더 효율적입니다.

  2. 환경 변수 추가 (Best Practice)
    파일의 맨 아래쪽에 다음 두 줄을 추가합니다. 이것이 바로 macOS에서 JAVA_HOME을 설정하는 가장 권장되고 미래 지향적인 방식입니다.
    # ======================================================
    # JAVA_HOME 설정 (macOS 표준 방식)
    # ======================================================
    export JAVA_HOME=$(/usr/libexec/java_home)
    export PATH=$JAVA_HOME/bin:$PATH

    이 두 줄의 코드가 왜 최선의 선택일까요? 각 구성 요소를 심층적으로 해부해 보겠습니다.

    • export: '내보내기'라는 의미의 이 명령어는, 여기서 설정된 변수를 현재 셸뿐만 아니라, 이 셸에서 실행되는 모든 하위 프로그램(자식 프로세스), 예를 들어 Maven 빌드나 Tomcat 서버 실행 스크립트에서도 사용할 수 있도록 전역적으로 만들어줍니다. export가 없다면 변수는 해당 셸 내부에서만 유효한 '지역 변수'가 되어버립니다.
    • JAVA_HOME=$(/usr/libexec/java_home): 이 구문이 바로 마법의 핵심입니다. 명령어 치환(Command Substitution)이라는 강력한 셸 기능으로, $(...) 안의 명령어를 먼저 실행하고, 그 명령어의 '표준 출력(결과값)'을 이 자리에 텍스트로 대체합니다. 즉, 셸이 시작될 때마다 /usr/libexec/java_home 명령이 동적으로 실행되어 반환된 최신 기본 JDK 경로가 JAVA_HOME 변수에 할당됩니다. 이 방식 덕분에 나중에 자바를 업데이트하거나 새로운 버전을 설치해도 이 설정 파일을 다시 수정할 필요가 없어집니다. 시스템이 알아서 최신 버전을 인식하고 JAVA_HOME을 갱신해 주기 때문입니다.
    • export PATH=$JAVA_HOME/bin:$PATH: PATH는 터미널이 java, javac, mvn과 같은 명령어의 실행 파일을 어느 디렉토리에서 찾아야 할지 알려주는 경로들의 목록입니다. 이 목록은 콜론(:)으로 구분됩니다. 이 줄의 의미는 "기존의 PATH 목록 맨 앞에 $JAVA_HOME/bin 디렉토리를 추가하라" 입니다. 이렇게 해야 터미널의 어느 위치에서든 java -version 같은 명령어를 전체 경로 없이 바로 실행할 수 있습니다. $JAVA_HOME/bin을 앞에 추가하는 이유는, 시스템의 다른 경로(예: /usr/bin/java)에 구버전 자바의 심볼릭 링크가 있을 경우, 우리가 설정한 JAVA_HOME의 자바를 우선적으로 사용하도록 만들기 위함입니다. :$PATH를 뒤에 붙여 기존 경로들을 보존하는 것은 매우 중요합니다. 이를 생략하면 시스템의 다른 기본 명령어들을 찾지 못하는 대참사가 발생할 수 있습니다.
  3. 변경사항 저장 및 적용
    nano 편집기에서는 Control + O 키를 누르고, 파일 이름을 확인한 후 Enter를 쳐서 저장합니다. 그리고 Control + X 키를 눌러 편집기를 종료합니다.
    마지막으로, 다음 명령어를 터미널에 입력하여 변경된 설정을 현재 열려있는 터미널 세션에 즉시 적용합니다.
    source ~/.zshrc

    이 과정을 거치면 터미널을 새로 열지 않아도 바로 JAVA_HOME이 적용되어 확인할 수 있습니다.

Step 2-B: Bash 사용자를 위한 설정 (~/.bash_profile 파일 수정)

Bash 셸을 사용한다면 과정은 Zsh와 99% 동일하지만, 셸이 시작될 때 읽는 설정 파일의 이름이 다릅니다. macOS의 터미널에서 실행되는 Bash는 '로그인 셸(Login Shell)'로 간주되므로, ~/.bashrc보다는 ~/.bash_profile 파일을 수정하는 것이 표준적인 방법입니다. (~/.bash_profile은 로그인 시 한 번만 로드되며, 보통 여기서 ~/.bashrc를 로드하도록 설정합니다.)

  1. .bash_profile 파일 열기
    nano ~/.bash_profile
  2. 환경 변수 추가 (내용은 Zsh와 완전히 동일합니다)
    # JAVA_HOME 설정 (macOS 표준 방식)
    export JAVA_HOME=$(/usr/libexec/java_home)
    export PATH=$JAVA_HOME/bin:$PATH
  3. 변경사항 저장 및 적용
    Control + O로 저장, Control + X로 종료 후, 다음 명령어로 설정을 즉시 적용합니다.
    source ~/.bash_profile

4. 최종 검증 및 전문가 팁: 자바 버전 관리와 전환의 기술

설정이 올바르게 완료되었는지 확인하는 것은 아무리 강조해도 지나치지 않습니다. 터미널에서 다음 명령어들을 차례로 실행하여 모든 것이 예상대로 동작하는지 꼼꼼히 확인하세요.

1. JAVA_HOME 변수 값 직접 확인

echo $JAVA_HOME

이 명령어는 /usr/libexec/java_home이 반환했던 기본 JDK 경로를 그대로 출력해야 합니다.

/Library/Java/JavaVirtualMachines/jdk-21.0.1.jdk/Contents/Home

2. 실행되는 Java 버전 확인

java -version

JAVA_HOME이 가리키는 버전의 정보가 상세하게 출력되어야 합니다.

java version "21.0.1" 2023-10-17 LTS
Java(TM) SE Runtime Environment (build 21.0.1+12-LTS-29)
Java HotSpot(TM) 64-Bit Server VM (build 21.0.1+12-LTS-29, mixed mode, sharing)

3. Java 컴파일러(javac) 경로 및 버전 확인

which javac
javac -version

which javac 명령어는 $JAVA_HOME/bin/javac 경로, 즉 위에서 확인한 JAVA_HOME 경로 아래의 bin/javac를 출력해야 합니다. 만약 다른 경로가 나온다면 PATH 설정의 우선순위에 문제가 있을 수 있습니다. javac -versionjava -version과 동일한 버전 정보(예: `javac 21.0.1`)를 보여줘야 합니다. 만약 `command not found` 오류가 발생한다면 PATH 설정에 오타가 있거나 누락된 것입니다.

고급 기술: 특정 자바 버전을 기본값으로 고정하기

최신 버전이 아닌, 특정 버전의 자바(예: 회사의 표준인 Java 11)를 터미널의 기본값으로 사용하고 싶을 때가 많습니다. 이때 /usr/libexec/java_home 유틸리티의 -v 옵션을 사용하면 매우 우아하게 해결할 수 있습니다.

~/.zshrc (또는 ~/.bash_profile) 파일을 다시 열고 JAVA_HOME 설정 부분을 다음과 같이 수정합니다.

# Java 11을 기본으로 설정
export JAVA_HOME=$(/usr/libexec/java_home -v 11)
export PATH=$JAVA_HOME/bin:$PATH

-v 옵션 뒤에 원하는 메이저 버전을 명시하면, 해당 메이저 버전 중에서 가장 최신 빌드 버전을 스마트하게 찾아 그 경로를 반환해 줍니다. 예를 들어 시스템에 11.0.15와 11.0.20이 모두 설치되어 있다면, -v 11은 11.0.20의 경로를 반환합니다.

만약 구형 프로젝트 때문에 자바 8(버전 표기법: 1.8)을 기본으로 사용해야 한다면 다음과 같이 수정합니다.

# Java 8 (1.8)을 기본으로 설정
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
export PATH=$JAVA_HOME/bin:$PATH

파일 수정 후에는 반드시 source ~/.zshrc 명령으로 변경사항을 적용하는 것을 잊지 마세요. 적용 후 java -version을 실행해보면 지정한 버전으로 깔끔하게 변경된 것을 확인할 수 있습니다. 이 방법은 하드코딩된 경로를 사용하는 것보다 훨씬 유연합니다.

프로페셔널 팁: 셸 함수로 자바 버전 실시간 전환하기

여러 프로젝트를 동시에 진행하며 자바 버전을 수시로 바꿔야 하는 개발자라면, .zshrc 파일을 매번 수정하는 것은 번거로운 일입니다. 이럴 땐 셸 함수(Shell Function)를 만들어두면 단 하나의 명령어로 버전을 즉시 변경할 수 있습니다. .zshrc 파일 맨 아래에 다음 코드를 추가해보세요.

# Java Version Switcher Functions
function setjdk() {
  if [ -z "$1" ]; then
    echo "사용 가능한 버전:"
    /usr/libexec/java_home -V | grep -E "\d+\.\d+\." | awk '{print $1}'
    return 1
  fi
  
  export JAVA_HOME=$(/usr/libexec/java_home -v $1)
  export PATH=$JAVA_HOME/bin:$PATH
  echo "JAVA_HOME이 다음으로 설정되었습니다:"
  echo $JAVA_HOME
  java -version
}

# 단축 별칭(Alias) 설정
alias jdk8='setjdk 1.8'
alias jdk11='setjdk 11'
alias jdk17='setjdk 17'
alias jdk21='setjdk 21'

source ~/.zshrc로 적용한 뒤, 터미널에서 jdk11, jdk17과 같은 명령어를 입력해보세요. JAVA_HOMEPATH가 즉시 해당 버전으로 변경되며, 마치 마법처럼 개발 환경이 전환되는 것을 경험할 수 있습니다.

5. 현대적인 대안: SDKMAN!으로 자바 버전 관리 자동화하기

위에서 설명한 방법은 macOS의 기능을 활용한 매우 표준적이고 훌륭한 방식이지만, 여러 버전을 매우 빈번하게 설치, 삭제, 전환해야 하는 개발자에게는 SDKMAN!과 같은 버전 관리 도구가 진정한 '게임 체인저'가 될 수 있습니다.

SDKMAN!은 자바뿐만 아니라 Groovy, Scala, Kotlin, Maven, Gradle 등 JVM 기반의 다양한 SDK(Software Development Kit) 버전을 간단한 명령어로 설치하고 관리하며 전환할 수 있게 해주는 강력한 커맨드라인 도구입니다. SDKMAN!을 사용하면 .zshrc 파일을 직접 수정할 필요 없이, 모든 과정을 자동화하여 관리해 줍니다.

SDKMAN!을 사용해야 하는 이유:
  • 설치의 간편함: sdk install java ... 한 줄이면 원하는 버전, 원하는 배포판의 JDK가 설치됩니다.
  • 자동 환경 설정: 설치 및 버전 전환 시 JAVA_HOME을 포함한 모든 환경 변수를 자동으로 설정하고 관리해 줍니다.
  • 다양한 SDK 지원: 자바 외에도 Maven, Gradle, Spring Boot CLI 등 다양한 개발 도구를 동일한 방식으로 관리할 수 있어 일관성이 높습니다.

SDKMAN! 설치:

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

설치 스크립트는 .zshrc.bash_profile에 필요한 초기화 코드를 자동으로 추가해 줍니다.

SDKMAN! 주요 명령어:

  • sdk list java: 설치 가능한 모든 자바 버전 목록을 배포판(Vendor)과 함께 보여줍니다. (예: Temurin, Zulu, Corretto 등)
  • sdk install java 17.0.8-tem: 특정 버전(예: Temurin 17.0.8)을 설치합니다.
  • sdk use java 17.0.8-tem: 현재 터미널 세션에서만 사용할 자바 버전을 임시로 지정합니다.
  • sdk default java 17.0.8-tem: 모든 터미널에서 기본으로 사용할 자바 버전을 영구적으로 지정합니다. 이 명령어가 내부적으로 JAVA_HOME을 관리합니다.
  • sdk current java: 현재 사용 중인 자바 버전을 보여줍니다.

아래 표는 수동 관리 방식과 SDKMAN!을 비교한 것입니다.

기능 수동 관리 (.zshrc + java_home) SDKMAN!
초기 설정 .zshrc 파일에 직접 스크립트 작성 필요 설치 스크립트 실행으로 자동 완료
JDK 설치 웹사이트에서 직접 다운로드 또는 Homebrew 사용 sdk install java <version> 명령어로 완료
버전 전환 .zshrc 수정 또는 직접 만든 셸 함수 사용 sdk use/default java <version> 명령어로 완료
관리 범위 Java만 직접 관리 Java, Maven, Gradle, Kotlin 등 다양한 SDK 통합 관리
의존성 macOS 내장 기능만 사용 (가벼움) SDKMAN! 스크립트 자체에 의존
추천 대상 시스템 동작 원리를 이해하고 싶거나, 소수의 버전만 사용하는 개발자 다수의 프로젝트와 다양한 SDK 버전을 빈번하게 다루는 개발자
중요: SDKMAN!을 설치하여 사용하기로 결정했다면, 이전에 .zshrc에 직접 추가했던 export JAVA_HOME=...export PATH=... 라인은 삭제하거나 주석 처리(라인 앞에 # 추가)하는 것이 좋습니다. 두 설정이 충돌하여 예기치 않은 문제를 일으킬 수 있습니다.

6. 최종 관문: FAQ 및 문제 해결 (Troubleshooting)

Q1: "zsh: command not found: java" 또는 "javac: command not found" 오류가 계속 발생합니다.

A: 이 오류는 99% 다음 두 가지 원인 중 하나입니다.

  1. Java가 실제로 설치되지 않았거나 시스템이 인식하지 못함: 가장 먼저 /usr/libexec/java_home -V 명령어로 시스템에 인식된 JDK가 있는지 확인하세요. 목록이 비어있다면 Adoptium (Temurin), Oracle Java 등에서 JDK를 먼저 설치해야 합니다. Homebrew를 사용한다면 brew install openjdk@17 과 같이 설치할 수 있습니다.
  2. PATH 설정 오류: JAVA_HOME은 설정했지만 export PATH=$JAVA_HOME/bin:$PATH 부분이 누락되었거나 오타가 있는 경우입니다. ~/.zshrc 파일을 다시 열어 해당 라인이 정확히 입력되었는지, $, : 같은 기호가 빠지지 않았는지 확인하세요. echo $PATH 명령어로 출력된 경로 목록의 맨 앞에 /.../jdk-XX.X.X.jdk/Contents/Home/bin 형태의 경로가 포함되어 있는지 반드시 확인해야 합니다.

Q2: 터미널에서는 버전이 잘 바뀌는데, IntelliJ나 VS Code 같은 IDE에서는 다른 버전의 자바를 사용합니다. 왜 그런가요?

A: 이는 오류가 아니라 매우 정상적이고 의도된 동작입니다. IntelliJ, Eclipse, VS Code와 같은 현대적인 IDE는 시스템의 전역 JAVA_HOME 설정보다 자체적인 프로젝트별/워크스페이스별 JDK 설정을 항상 우선시합니다. 이는 각 프로젝트가 요구하는 특정 JDK 버전에 정확히 맞춰 독립적인 개발 및 빌드 환경을 보장하기 위한 매우 중요한 기능입니다.

  • IntelliJ IDEA: File > Project Structure (단축키: Cmd + ;) > Project Settings > Project 에서 'Project SDK'를 변경할 수 있습니다. Gradle/Maven 프로젝트의 경우, 빌드 설정(Build, Execution, Deployment > Build Tools > Gradle > Gradle JVM)을 별도로 지정해야 할 수도 있습니다. IDE는 시스템에 설치된 JDK들을 대부분 자동으로 찾아주지만, 못 찾는 경우 + 버튼을 눌러 JDK 경로(/Library/Java/JavaVirtualMachines/...)를 직접 추가해주면 됩니다.
  • Visual Studio Code (VS Code): Java Extension Pack이 설치된 상태에서 Cmd + Shift + P를 눌러 명령 팔레트를 열고 'Java: Configure Java Runtime'을 검색하여 실행하세요. 여기서 프로젝트 JDK 경로(java.configuration.runtimes)와 기본 실행 환경 등을 그래픽 인터페이스를 통해 손쉽게 설정하고 프로젝트별로 다른 버전을 지정할 수 있습니다.

Q3: Apple Silicon (M1/M2/M3) Mac을 사용 중입니다. Intel(x86_64) 버전과 ARM(arm64) 버전 JDK 중 무엇을 설치해야 하나요?

A: 결론부터 말하면, 가능한 한 항상 arm64 네이티브 버전을 사용해야 합니다. 네이티브 아키텍처에서 실행될 때 훨씬 뛰어난 성능과 전력 효율을 보여주기 때문입니다. /usr/libexec/java_home -V 출력에서 (arm64)로 표시된 JDK를 우선적으로 사용하세요. 하지만, 간혹 ARM을 지원하지 않는 오래된 네이티브 라이브러리(JNI)를 사용하는 레거시 프로젝트나 특정 도구를 실행해야 하는 예외적인 경우, Intel(x86_64) 버전 JDK를 설치하고 macOS의 Rosetta 2를 통해 실행해야 할 수도 있습니다. 두 버전 모두 설치해두고 필요에 따라 위에서 배운 버전 전환 기술을 활용하는 것이 현명한 전략입니다.

Q4: Homebrew로 자바를 설치했는데 경로가 이상합니다. 어떻게 해야 하나요?

A: Homebrew(brew install openjdk)로 설치하면 자바는 /opt/homebrew/Cellar/openjdk/... 와 같은 경로에 설치됩니다. 하지만 Homebrew는 /opt/homebrew/opt/openjdk/libexec/openjdk.jdk 와 같은 고정된 경로로 심볼릭 링크(Symbolic Link, 바로가기)를 만들어 줍니다. 더 중요한 것은, 설치 후 Homebrew가 알려주는 메시지에 따라 /opt/homebrew/opt/openjdk/binPATH에 추가하도록 권장한다는 점입니다. 하지만 이 방식은 /usr/libexec/java_home 유틸리티와는 별개로 동작하여 혼란을 줄 수 있습니다. 가장 좋은 방법은 Homebrew로 설치하더라도 JAVA_HOME 설정은 이 글에서 설명한 export JAVA_HOME=$(/usr/libexec/java_home) 방식을 그대로 사용하는 것입니다. macOS는 Homebrew로 설치된 JDK도 정상적으로 인식하여 java_home 유틸리티 목록에 포함시켜 주기 때문입니다. 이것이 가장 일관성 있고 표준적인 방법입니다.


이 가이드를 통해 macOS에서의 JAVA_HOME 설정과 자바 버전 관리에 대한 모든 궁금증이 명쾌하게 해결되었기를 바랍니다. 이제 여러분은 어떤 복잡한 프로젝트 요구사항 앞에서도 당황하지 않고, 자신감 있게 자바 개발 환경을 구축하고 자유자재로 제어할 수 있는 개발자로 거듭났을 것입니다. 더 이상 환경 설정에 시간을 뺏기지 말고, 창의적인 코드 작성에 집중하세요!

Post a Comment