요즘IT
위시켓
최근 검색어
전체 삭제
최근 검색어가 없습니다.

개발자에게 커피 한 잔은 바쁜 하루에 찾아오는 작은 여유가 아닐까 생각합니다. 저처럼 생각하는 분이 계시겠죠?

회원가입을 하면 원하는 문장을
저장할 수 있어요!

다음

회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!

확인

개발

개발 런타임 환경 구축하기: Java편

년차,
어떤 스킬
,
어떤 직무
독자들이 봤을까요?
어떤 독자들이 봤는지 궁금하다면?
로그인

개발자에게 커피 한 잔은 바쁜 하루에 찾아오는 작은 여유가 아닐까 생각합니다. 저처럼 생각하는 분이 계시겠죠?

 

조금 엉뚱한 시작이었습니다. 오늘 소개하고자 하는 주제가 커피 이름에서 비롯된 언어, ‘자바(Java)’의 개발 환경 구성에 대한 이야기이기 때문입니다. 자바의 아버지 제임스 고슬링은 자신이 만든 프로그래밍 언어에 때마침 그가 마시고 있던 커피 이름인 ‘자바'를 붙였다고 합니다.

 

오늘날 자바는 프로그래밍을 배우고자 하는 사람부터 엔터프라이즈에 이르기까지 매우 다양한 환경에서 사용되고 있습니다. 그뿐만 아니라 오랜 시간 자바가 사용되어 오면서 자바 VM(이하 JVM)을 같이 사용하는 코틀린, 스칼라, 클로져, 그루비 같은 언어들도 등장했습니다. 이를 보고 있으면 이 세상은 온통 자바로 가득차 있지 않을까 생각도 듭니다.

 

<출처: 오라클 웹사이트>

 

JDK 개발은 어쩌다 오라클과 커뮤니티로 나뉘어졌을까?

제가 자바를 처음 본 1998년 쯤에는 지방 서점의 서가에도 “자바 1.2”를 다루는 책이 있었을 정도였으니, 발표 이후 빠르게 자바 프로그래밍 열풍이 불지 않았나 생각됩니다. 조금 더 시간이 지나고 2002년경, 자바는 이미 데스크톱 애플리케이션을 벗어나 웹 사이트를 만드는 일에도 활발히 쓰이고 있었습니다. 기존에는 자바로 웹 사이트를 만들기 위해 전통적으로 서블릿 기술을 사용했지만, J2EE에 JSP 기술이 들어오면서 자바 기반 웹 사이트 개발이 순식간에 인기를 얻었습니다.

 

2010년에는 변화가 있었습니다. 그때까지 자바를 만들고 무료로 공급해오던 썬마이크로시스템즈가 오라클에 인수된 거죠. 이후 오라클은 무료였던 자바를 기업에 패키지 라이선스 형태로 공급합니다. 처음에는 개인 사용자가 직접 가져다 설치하는 것까지는 막지 않았지만, 2019년부터는 자사가 패키징해서 판매하던 오라클 자바를 구독 기반으로 전면 유료화했습니다.

 

지금도 그렇지만 이 당시에도 자바는 안드로이드의 핵심 구성 요소로 사용되었습니다. 그동안 무료로 오라클 자바를 사용해 안드로이드를 만들던 구글은 물론이고 IBM, 레드햇 같은 기업까지 오라클 자바를 사용하는 데 부담을 느끼게 됩니다.

 

한편 오라클은 자바를 유료화하기 이전인 2017년부터 자바 엔터프라이즈 에디션(Java EE)을 오픈소스 재단이 이끌어 주기를 희망했습니다. 오라클 SE에 집중하기 위해서였죠. Java EE 개발을 지속할 수 있는 오픈소스 재단은 Apache Foundation과 Eclipse IDE를 만들던 Eclipse Foundation이었고, 결과적으로 J2EE는 Eclipse Foundation에 이관됩니다. 그리고 2년 후 오라클이 자바 유료화를 결정하게 되죠.

 

자바 SDK 유료화 정책 이후, 프로그램을 개발하는 개발사들은 물론이고 개발자들도 혼란을 크게 겪었습니다. 이 당시에는 수많은 자바 프로그램이 오라클에서 배포하는 자바(Hot Java) 기능에 크게 의존하고 있었기 때문이었습니다.

 

이때 자바 유료화 사건으로 어려움을 겪은 이들이 한데 모여 OpenJDK를 기반으로 라이선스에 자유로운 JVM을 만들게 되었습니다. 지금은 Temurin이라 불리는 JVM이 바로 OpenJDK 기반입니다. 다만 이 OpenJDK는 2006년부터 썬마이크로시스템즈가 오픈 소스로 JVM을 공개한 것입니다. 따라서 OpenJDK 역시 오라클이 상표권을 가지고 있습니다.

 

기업에서도 JVM을 따로 개발하기 시작했습니다. 특히 클라우드의 탄생 이후 개발이 가속화되었죠. Eclipse를 처음 만들었던 IBM은 물론이고 알리바바, 화웨이도 독자적으로 JVM을 개발했죠. 자바 유료화 정책 이후 얼마간의 시간이 지난 지금, 개발자들은 개발 환경과 고객 요구 사항에 따라 JVM을 취사 선택하게 되었습니다.

 

전통적으로 JDK 설치는 JDK 프로그램을 받고 환경 변수를 설정해야 합니다. 그런데 JDK와 SDK가 늘어나니 환경 설정에 애를 먹게 되었습니다. 바로 여기에서 오늘의 주제인 자바 개발 환경 구축의 문제가 시작됩니다.

 

 

다양해도 너무 다양한 JVM과 자바 기반 개발 생태계

자바가 처음 등장한 1995년 이후, 자바 기반 프로그램과 개발 생태계는 놀라울 정도로 크게 성장했습니다. 특히 2003년에 발표된 자바 프레임워크 Spring은 20여년 지난 지금도 자바 개발 생태계의 대부분을 차지할 정도로 인기를 끌고 있습니다.

 

자바 언어로 작성된 파일은 기본적으로 JVM을 거쳐 해석할 수 있는 형태의 파일로 변환되어야 합니다. 보통 이런 과정을 컴파일이라고 합니다. 이 과정을 마치고 나면 JVM이 컴파일된 파일을 메모리에 읽어들여 실행합니다.

 

이때 자바 언어로 작성된 파일의 양이 적으면 JVM에서 컴파일 하는 시간이나 오류가 발생할 가능성이 높지 않습니다. 하지만 컴파일하려는 파일이 많아지면 문제가 복잡해집니다. 특히 이 파일들이 연관성을 가지고 있으면, 컴파일할 때 이들의 관계성을 자바 컴파일러에게 알려주어야 합니다.

 

C언어나 C++ 같은 언어도 이런 문제에서 자유롭지 않았습니다. 따라서 많게는 수십 개, 수백 개까지 연관 관계를 가지는 파일을 쉽게 컴파일하도록 도와주는 Make 같은 도구를 사용했습니다. 자바에도 같은 이유로 자바 컴파일을 쉽게 도와주는 Ant라는 도구가 있습니다. 하지만 Ant 등장 이후 자바 개발 생태계는 프로그램의 종속성 관리 문제에 부딪히게 되었습니다.

 

여기에서 ‘종속성’이란 프로그램이 동작하기 위해 다른 라이브러리를 필요로 하는 것을 의미합니다. 종속성 문제는 기존의 C, C++ 같은 언어에서도 발생하는 문제로, 개발자는 컴파일러에게 종속성 라이브러리가 어떤 경로에 있는지 늘 알려주어야 했습니다.

 

자바의 경우, 이런 문제를 해결하기 위해 Maven, Gradle 같은 도구가 차례대로 발표되었습니다. 다만 개발 생태계에서는 어떤 도구 하나가 등장했다고 모든 사람이 빠르게 그 도구를 사용하지는 않습니다. 프로젝트 환경에 따라 다른 도구를 선택하기도 하죠. 그렇기 때문에 어떤 프로그램은 Ant를, 어떤 프로그램은 Maven, 어떤 프로그램은 Gradle을 사용하기도 합니다.

 

필요할 때마다 이런 도구를 설치하는 일은 번거롭습니다. 웹 사이트를 방문해 도구를 다운로드 받고 어디서든 실행할 수 있도록 PATH 환경 변수에 프로그램 설치 경로를 추가해야 합니다. 게다가 프로젝트에 따라 다양한 버전이 사용되기도 합니다. 버전에 따라 도구의 기능 등이 바뀌기도 하기 때문입니다. 이런 경우 개발자는 어떤 도구를 어디에 설치했는지 기억하기도 어렵습니다. 특정 도구의 버전을 바꿔가며 실행하려면 PATH 환경 변수 역시 일일이 바꿔야 합니다.

 

 

SDKMAN 설치하기

 

<출처: sdkman.io>

 

SDKMAN은 이런 문제를 해결하기 위해 2012년에 처음 시작된 프로젝트입니다. 이 도구는 JDK와 자바 개발 생태계를 이루는 SDK(e.g. Tomcat, Maven, Gradle)들을 설치하고 사용하는데 도움을 줍니다. 다만 SDKMAN은 POSIX 시스템 용으로만 사용할 수 있습니다. 다시 말해 맥과 리눅스 환경에서만 사용 가능하고 윈도우에서는 사용할 수 없습니다.

 

SDKMAN의 설치부터 알아보겠습니다. 터미널에서 다음 명령을 사용해 설치합니다.

 

$ curl -s "https://get.sdkman.io" | bash

 

설치가 끝난 다음, 셸을 다시 시작하면 SDKMAN을 사용할 수 있게 됩니다. SDKMAN의 사용 명령은 sdk로 이 명령에서 어떤 기능을 지원하는지 살펴보시길 바랍니다.

 

 

SDKMAN을 설치하고 나서 가장 먼저 할 일

SDKMAN은 기본적으로 시스템에 설치되어 있는 JDK나 SDK를 인식하지 못합니다. 따라서 시스템에 설치되어 있는 도구를 미리 인식시켜줘야 합니다. 이 단계를 생략하면 SDKMAN으로 설치한 JDK나 SDK로 전환이 시작됩니다. 개발자가 시스템에 설치된 JDK나 SDK가 어떤 경로에 있었는지 모두 기억하기는 힘들기 때문에 이후에 다시 돌아가려고 해도 돌아가기 쉽지 않습니다.

 

미리 설치한 JDK와 SDK를 SDKMAN에 인식시키는 과정부터 시작해보겠습니다. 우선 자바가 어떤 경로에 설치되어 있는지 확인해야 합니다. 여러분이 리눅스나 맥을 사용하고 있다면 JDK가 어디에 설치되어 있는지 다음 명령으로 확인합니다.

 

$ command -v java

 

데비안/우분투 리눅스는 실행 결과로 /usr/bin/java가 출력될 텐데요, 이 경로를 그대로 사용하면 안됩니다. 이렇게 출력되는 것은 데비안/우분투 리눅스가 명령을 쉽게 사용할 수 있도록 심볼릭 링크를 걸어준 것 뿐입니다. /usr/bin/java가 실제 어떤 파일을 가리키고 있는지 확인하려면 다음 명령을 실행합니다.

 

$ ls -l /usr/bin/javac/etc/alternatives/javac

 

명령의 결과로 /etc/alternatives/java가 출력됩니다. 그러나 사실 이 링크도 심볼릭 링크입니다. 데비안/우분투 리눅스는 동일한 프로그램의 버전이 여러개 설치되는 것을 관리하기 위해 데비안에서 심볼릭 링크 관리 시스템(이하 alternatives 시스템)을 제공합니다. 심볼릭 링크 관리 명령어는 dpkg 패키지에서 제공합니다. 따라서 root 권한으로 다음 명령을 실행해야 실제 자바가 어디에 설치되어 있는지 확인할 수 있습니다.

 

$ update-alternatives --list javac

 

예를 들어 컴퓨터에 openjdk 8 버전이 설치되어 있다면, 다음 결과가 출력될 겁니다.

 

/usr/lib/jvm/java-8-openjdk-amd64/bin/javac

 

여기 설치된 JDK의 홈 디렉터리는 /bin/javac를 제외한 나머지 경로입니다. 맥은 alternatvies 시스템이 없기 때문에 command 명령으로 확인할 수 있습니다. 데비안/우분투 리눅스는 자바 외에도 Ant나 maven 등 SDK 역시 시스템 패키지로 제공하기 때문에 같은 방법으로 위치를 확인할 수 있습니다. Ant와 maven은 데비안/우분투 리눅스 한정으로 /usr/share/ant, /usr/share/maven에 설치되어 있습니다.

 

JDK 또는 SDK의 기본 설치 경로를 확인했으면, 이를 SDKMAN에 등록해줍니다. JDK를 등록하는 경우 아래 명령어를 쓸 수 있습니다.

 

$ sdk install java system /usr/lib/jvm/java-8-openjdk-amd64

 

이때 여러분이 주의하며 입력할 부분은 sdk install java 이후 부분입니다. system이라고 표기한 영역은 SDKMAN에서 사용할 별칭입니다. 이어 경로 부분은 자바가 어디 설치되어 있는지 확인하기 위해 사용합니다. 명령의 실행 결과는 다음과 같습니다.

 

Linking java system to /usr/lib/jvm/java-8-openjdk-amd64
Done installing!

 

Ant나 Maven도 이와 같은 방법으로 등록하면 됩니다.

 

 

SDKMAN 사용하기

SDKMAN을 사용하려면 앞서 설명한 것과 같이 sdk 명령을 사용해야 합니다. 셸에서 sdk 명령을 실행하면 다음과 같은 화면을 볼 수 있습니다.

 

NAME
    sdk - The command line interface (CLI) for SDKMAN!

SYNOPSIS
    sdk <subcommand> [candidate] [version]

DESCRIPTION
    SDKMAN! is a tool for managing parallel versions of multiple JVM related
    Software Development Kits on most Unix based systems. It provides a
    convenient Command Line Interface (CLI) and API for installing, switching,
    removing and listing Candidates.

SUBCOMMANDS & QUALIFIERS
    help         [subcommand]
    install      <candidate> [version] [path]
    uninstall    <candidate> <version>
    list         [candidate]
    use          <candidate> <version>
    config       no qualifier
    default      <candidate> [version]
    home         <candidate> <version>
    env          [init|install|clear]
    current      [candidate]
    upgrade      [candidate]
    version      no qualifier
    offline      [enable|disable]
    selfupdate   [force]
    update       no qualifier
    flush        [tmp|metadata|version]

EXAMPLES
    sdk install java 17.0.0-tem
    sdk help install

 

출력 결과에 candidate라는 단어가 자주 등장하는데요. 이는 SDKMAN을 사용할 때, 반드시 익숙해져야 하는 개념입니다. 여기서 candidate는 SDKMAN이 관리할 JDK나 SDK를 말합니다. 자바나 vert.x를 설치한다면 candidate는 java, vertx 라는 이름으로 나타납니다. candidate의 이름은 후반부에 설명할 sdk list 명령을 통해 확인할 수 있습니다. 이제 SDKMAN을 사용할 때 자주 쓰는 명령어 세트를 살펴보겠습니다.

 

sdk list

sdk list 명령은 2가지 기능이 있습니다. 첫 번째 기능은 SDKMAN에서 설치할 수 있는 candidate 목록을 출력하는 기능입니다. 두 번째 기능은 candidate 별로 설치할 수 있는 버전과 설치 및 사용 여부를 표시하는 기능입니다.

 

SDKMAN으로 설치할 수 있는 candidate 목록을 보려면 sdk list 명령을 인자 없이 호출하면 됩니다.

 

$ sdk list

 

이 명령의 실행 결과는 다음과 같습니다.

 

========================================================================
Available Candidates
========================================================================
q-quit                                  /-search down
j-down                                  ?-search up
k-up                                    h-help

------------------------------------------------------------------------
Apache ActiveMQ (Classic) (5.17.1)                  https://activemq.apache.org/

Apache ActiveMQ(r) is a popular open …

                                                  $ sdk install activemq
... 중략

 

sdk install 뒤에 나오는 문자열이 candidate의 이름입니다. 예시 결과를 보면, 첫 번째 항목인 “Apache ActiveMQ”의 candidate 이름은 activemq인 것을 알 수 있습니다.

 

sdk list의 두 번째 기능은 candidate의 설치 가능 버전과 설치 여부를 확인하는 기능입니다. 예를 들어 candidate가 java라면 다음과 같이 명령합니다.

 

$ sdk list java

 

자바는 다양한 벤더가 개발하고 있기 때문에, 아래와 유사한 결과가 나오게 됩니다.

 

=======================================================================
Available Java Versions for Linux 64bit                                
=======================================================================
Vendor        | Use | Version      | Dist    | Status     | Identifier 
----------------------------------------------------------------------- 
Corretto      |     | 22           | amzn    |            | 22-amzn      
              |     | 21.0.2       | amzn    |            | 21.0.2-amzn
              |     | 21.0.1       | amzn    |            | 21.0.1-amzn
Dragonwell    |     | 8.0.382      | albba   |            | 8.0.382-albba
... 생략

 

여기에서 Identifier 열에 나오는 이름이 자바의 candidate입니다. 다만 candidate가 java인 경우, 우리가 별도로 등록한 candidate 버전은 나오지 않습니다. 이때 SDKMAN을 사용해 설치한 자바 버전이 사용할 수 있는지 확인하려면 출력 결과의 Use 열과 Status 열을 보면 됩니다.

 

Corretto      | >>> | 22           | amzn    | installed  | 22-amzn

 

JDK가 아닌 다른 Candidate는 sdk list 명령으로 이와 비슷한 출력 결과를 볼 수 있습니다.

 

$ sdk list ant
=======================================================================
Available Ant Versions
=======================================================================
  * 1.10.13             1.9.14
    1.10.12             1.9.13
    1.10.11             1.9.12
    1.10.10             1.9.11
    1.10.9              1.9.10
    1.10.8              1.9.9
    1.10.7              1.9.8
    1.10.6              1.9.7
    1.10.5          > + system
    1.10.4
    1.10.3
    1.10.2
    1.10.1
    1.10.0
    1.9.15

=======================================================================
+ - local version
* - installed
> - currently in use
=======================================================================

 

출력 결과를 볼까요? SDKMAN을 사용해 설치할 수 있는 candidate 버전, 해당 버전의 설치 여부, 로컬 컴퓨터에 있던 버전인지 여부, 사용 중인 버전인지 등을 확인하는 기호가 나옵니다. 이 기호의 범례는 출력 결과 아래에서 확인할 수 있습니다.

 

sdk install

sdk install는 candidate를 설치하는 명령입니다. 기본적인 명령의 형식은 다음과 같습니다.

 

sdk install [candidate] [version]

 

앞에서 예시로 본 자바 버전을 설치해 보겠습니다. 다음 명령을 실행하면 됩니다.

 

$ sdk install java 22-amzn

 

JDK가 아닌 SDK라면, candidate 이름 뒤에 버전 명을 써주면 됩니다. sdk instal 명령은 특별히 로컬 컴퓨터에 설치되어 있는 candiate를 추가해줄 수 있는데 이 때는 다음과 같이 명령을 실행합니다.

 

$ sdk install [candidate] [version 별칭] [candidate local home]

 

로컬 컴퓨터에 설치되어 있는 candidate를 설치할 땐 버전의 별칭을 system으로 하면 나중에 기억하기 편합니다. candidate local home은 프로그램의 홈 디렉터리로 “/bin/command”가 있는 디렉터리라고 이해하면 됩니다.

 

sdk uninstall

sdk uninstall은 이미 설치되어 있는 candidate를 컴퓨터에서 제거하기 위해 사용합니다. 명령 형식은 다음과 같습니다.

 

$ sdk uninstall [candidate] [version]

 

예를 들어 자바 버전 중 Corretto에서 배포된 22버전의 JDK를 제거해보겠습니다. 아래와 같이 명령을 실행합니다.

 

$ sdk uninstall java 22-amzn

 

sdk uninstall 명령은 우리가 로컬 컴퓨터에 설치했던 버전도 제거할 수 있습니다. 만약 우리가 설치한 candidate 버전을 지우면, 홈 경로가 기억나지 않을 수 있으니 주의하시길 바랍니다.

 

sdk use

sdk use 명령은 우리가 셸을 실행하는 동안 사용할 candidate 버전을 지정할 때 사용합니다. 명령어의 기본 형식은 다음과 같습니다.

 

$ sdk use [candidate] [version]

 

예를 들어 Ant의 1.10.13과 “system” 버전이 설치되어 있다면, 이런 명령을 사용합니다.

 

$ sdk use ant 1.10.13

 

이 명령을 실행한 다음 Ant 명령을 실행하면, 항상 1.10.13 버전이 실행될 겁니다. 나중에 “system” 버전을 실행하려면 다음과 같이 실행합니다.

 

$ sdk use ant system

 

sdk default

sdk default 명령은 우리가 셸을 실행하는 동안 sdk use를 사용하지 않아도 기본으로 사용할 candidate 버전을 지정할 때 사용합니다. 명령의 형식은 다음과 같습니다.

 

$ sdk default [candidate] [version]

 

예를 들어 Ant를 셸에서 입력했을 때, 항상 1.10.13을 사용하겠다고 한다면 다음 명령을 실행합니다.

 

$ sdk default ant 1.10.13

 

특정 candidate에 대한 기준 버전이 없다면 SDKMAN 명령 실행이 실패할 수도 있습니다.

 

sdk current

마지막 주요 기능입니다. sdk current는 우리가 셸에서 사용하고 있는 candidate의 버전이 무엇인지 출력해 줍니다. 다음과 같은 명령 형식을 사용합니다.

 

$ sdk current [candidate]

 

예를 들어 어떤 Ant 버전을 사용하고 있는지 확인하려면 다음 명령을 실행합니다.

 

$ sdk current ant

 

 

SDKMAN를 윈도우에서 사용할 수 없을까?

지금까지 살펴본 것처럼, SDKMAN은 자바와 자바 개발 생태계 한정으로 편리한 개발을 돕는 정말 멋진 도구라고 생각합니다. 하지만 SDKMAN에도 치명적인 단점이 있습니다. SDKMAN 설치하기 부분에 언급한 내용인데요, 바로 윈도우에서 사용할 수 없다는 것입니다. 윈도우에서 사용할 수 있는 버전이 있는 pyenv와 다르게 말입니다.

 

이런 어려움에도 불구하고 윈도우에서 SDKMAN을 쓰려면 방법이 아예 없지는 않습니다. WSL 안에 SDKMAN을 설치하고 사용하거나 Git이 설치되어 있다면 Git Bash 프로그램을 사용할 수 있습니다. GIt Bash 프로그램을 사용하는 경우 설치 과정과 사용 과정이 좀 더 복잡해지므로 추천하지 않습니다.

 

다만 WSL을 사용하는 경우 윈도우에 설치되어 있는 자바 IDE가 WSL에 있는 자바를 사용하도록 설정해야 합니다. WSL에 있는 자바를 사용할 수 있는 IDE는 IntelliJ IDEA Professional 버전 뿐입니다. 따라서 Eclipse나 최근 많이 쓰이는 Visual Studio Code에서의 동작 여부는 확실하게 말하기 어렵습니다.

 

 

마치며

이번 글에서는 자바 기반 개발 환경을 구성하는 데 유용하게 사용할 수 있는 SDKMAN을 살펴봤습니다. JDK나 자바 기반의 SDK 버전 관리에 어려움을 겪던 분들에게 SDKMAN이 큰 도움이 될 것입니다.


요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.

좋아요

댓글

공유

공유

댓글 0
작가
7
명 알림 받는 중

작가 홈

작가
7
명 알림 받는 중
"Flask 기반의 파이썬 웹 프로그래밍", "Vue.js 첫걸음"을 집필하고 "파이썬 코딩 클럽 LV2, LV3"를 공역했습니다. 메가존소프트에서 구글 클라우드 아키텍트로 일하고 있으며 파이썬과 PostgreSQL만 연관되면 눈을 번쩍입니다. 최근엔 Rust에 눈독을 들이고 있는 중입니다. 다같이 파이썬과 Rust로 시스템 정복을 노려봅시다!

좋아요

댓글

스크랩

공유

공유

지금 회원가입하고,
요즘IT가 PICK한 뉴스레터를 받아보세요!

회원가입하기
요즘IT의 멤버가 되어주세요! 요즘IT의 멤버가 되어주세요!
요즘IT의 멤버가 되어주세요!
모든 콘텐츠를 편하게 보고 스크랩해요.
모든 콘텐츠를 편하게 보고 스크랩 하기
매주 PICK한 콘텐츠를 뉴스레터로 받아요.
매주 PICK한 콘텐츠를 뉴스레터로 받기
로그인하고 무료로 사용하기