이번 글에서는 macOS에서 JDK 버전 관리 방법을 다룹니다.
nodejs에서는 `n` 혹은 `nvm`과 같은 버전을 관리 툴을 사용하면 손쉽게 새로운 버전을 확인, 설치할 수 있고 설치된 버전을 변경, 삭제할 수 있습니다. java에서는 설정할 것이 노드에 비해 더 많기 때문에 미래의 저와 다른 분들에게 도움이 되고자 블로그에 정리해 봅니다.
이 글은 설정 과정과 이유를 담고 있습니다. 빠르게 설정만 필요하신 분들은 글 아래의 `정리` 부분을 바로 읽으시면 시간을 아끼실 수 있습니다.
Homebrew 설치
`Homebrew`는 macOS의 오픈소스 패키지 관리 시스템입니다. CLI기반 툴이라 처음 사용하시면 어색할 수 있지만 JDK 버전 관리 글을 읽고 있는 분이라면 익숙하실 거라 생각합니다. homebrew 페이지에서 설치 스크립트를 복사해 설치해 줍니다.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Homebrew를 이용한 JDK 설치
- JDK 설치
homebrew에서 설치 가능한 formula에서 "java"와 "jdk"를 검색하면 `java`, `java11`, `openjdk`, `openjdk@XX`가 검색됩니다.
`openjdk@XX`는 XX버전 JDK를 의미하고 `java`와 `openjdk`는 현시점 최신 GA 버전(글 쓰는 시점 기준 v21.0.1)을 의미합니다. 즉, `java`, `openjdk`, `openjdk@21`은 같은 formula입니다.
이 중 원하는 버전을 설치해 줍니다. 저는 `java`(`openjdk@21`)와 `openjdk@11`을 설치하겠습니다.
brew search --formula java
brew search --formula jdk
brew install --formula java
brew install --formula openjdk@11
- symlink 생성
이제 설치가 잘 완료되었는지 아래 명령어로 확인해 봅니다.
- `java -version`: 현재 사용 중인 JDK 버전 확인
- `/usr/libexec/java_home -V`: 설치된 모든 JDK 버전 확인
두 명령어 모두 정상적으로 실행되지 않습니다.
이는 macOS가 homebrew에 의해 설치된 JDK를 인식하지 못해서 그렇습니다.
`java -version` 명령어를 실행하면 macOS는 JDK를 `/Library/Java/JavaVirtualMachines/`에서 찾습니다.
하지만 homebrew로 설치한 JDK는 다른 위치에 저장되기 때문에 인식하지 못하는 것입니다.
homebrew로 설치한 파일아 저장되는 위치는 아래와 같습니다.
- M1 Mac: `/opt/homebrew/Cellar`
- Intel Mac: `/usr/local/Cellar`
또한 위 경로에 설치된 파일들은 `/opt/homebrew/opt`에 soft-link를 생성합니다.(후이 이 soft-link 파일의 symlink를 생성합니다.)
homebrew로 설치한 JDK에 대한 soft-link를 macOS가 java 실행파일을 찾는 위치(`/Library/Java/JavaVirtualMachines/`)에 생성해줘야 합니다. 방법은 명령어 `brew info <formula>`를 통해 알 수 있습니다.
Caveats 부분을 보면 `openjdk`는 keg-only이며 OS가 JDK를 찾게 하기 위해 symlink를 생성하고 환경 변수 `PATH`를 추가하라고 나옵니다. 이런 번거로운 과정이 있는 이유는 `formula`는 `keg-only`이기 때문입니다. (참고: docs.brew.sh)
아래 명령어로 `/Library/Java/JavaVirtualMachines/`에 symlink를 생성합니다.
brew info openjdk
brew info openjdk@11
sudo ln -sfn /opt/homebrew/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk
sudo ln -sfn /opt/homebrew/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdk
이제 처음에 실패했던 두 개의 명령어를 실행해 보면 원하는 정상적으로 작동하는 것을 확인할 수 있습니다.
JDK 버전 변경하기
- 버전 변경
환경 변수 `JAVA_HOME`은 OS에게 JDK의 위치를 직접 알려주는 환경 변수입니다. 따라서 `JAVA_HOME` 변수 값을 변경해 사용할 JDK를 변경할 수 있습니다.
또한 `/usr/libexec/java_home`을 이용해 `/Library/Java/JavaVirtualMachines/`에 저장된 JDK의 위치를 알 수 있습니다.
여기서 사용할 플래그는 `-v <version>`입니다. v가 소문자임에 주의해 주세요. (앞서 설치된 모든 JDK 버전을 확인하기 위해 사용했던 플래그 `-V`는 대문자입니다.)
플래그를 이용한 명령어로 설치된 JDK 중 11 버전으로 필터링하면 아래와 같은 경로가 출력됩니다. (`/usr/libexec/java_home -v 11`)
`java_home -v <version>`을 이용해 `JAVA_HOME` 변수를 설정하면 쉽게 현재 사용하는 버전을 변경할 수 있습니다.
export JAVA_HOME=`/usr/libexec/java_home -v 11`
- 별칭 생성
위 명령어에 별칭을 생성하면 더 간편하게 버전을 변경할 수 있습니다.
vim ~/.zshrc
## .zshrc에 추가
# alias java-11="export JAVA_HOME=`/usr/libexec/java_home -v 11.0.21`; java -version"
# alias java-21="export JAVA_HOME=`/usr/libexec/java_home -v 21.0.1`; java -version"
source ~/.zshrc
이제 `java-11`, `java-21` 명령어를 이용해 버전을 변경할 수 있습니다.
정리
1. Home brew 설치
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
2. JDK 설치
# XX 버전 JDK 설치
brew install --formula openjdk@XX
# 최신 GA 버전 JDK 설치
brew install --formula openjdk
# 혹은
brew install --formula java
3. symlink 생성
# 아래 명령어로 symlink 생성 명령어 확인
brew info openjdk@XX
# openjdk 일 경우 아래 명령어로 symlink 생성
sudo ln -sfn /opt/homebrew/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk
4. 원하는 버전으로 변경
export JAVA_HOME=`/usr/libexec/java_home -v XX`
5. 별칭 명령어 생성
alias java-11="export JAVA_HOME=`/usr/libexec/java_home -v XX`; java -version"
p.s. 인터넷에 mac에서 자바 버전 변경하는 방법을 검색하면 많은 블로그에서 `brew tap adoptopenjdk/openjdk` 명령어를 이용하는 방법을 설명합니다.
`brew tap <user/repo>` 명령어는 `https://github.com/<user>/homebrew-<repo>`의 레포지토리를 `${brew --repository}/Library/Taps/`에 클론 한 뒤 `homebrew/core` 레포지토리에 있는 formula처럼 install/uninstall 할 수 있게 해주는 명령어입니다.
`https://github.com/adoptopenjdk/homebrew-openjdk`에 들어가 확인해 보면 해당 레포지토리는 deprecated 되어 `temurin` cask를 사용하라고 합니다.
참고
글 내용 관련: https://medium.com/@manvendrapsingh/installing-many-jdk-versions-on-macos-dfc177bc8c2b
homebrew 개념, 사용 관련: https://docs.brew.sh/Formula-Cookbook#homebrew-terminology
brew tap 관련: https://velog.io/@haejeonghy/Homebrew-Tap-%EC%82%AC%EC%9A%A9
'Languages > Java' 카테고리의 다른 글
[Java] Thread와 Concurrent 패키지 그리고 Virtual Thread (1) | 2024.01.16 |
---|---|
Java로 알아보는 비트 연산과 시프트 연산 (0) | 2023.08.22 |