자바 버전 지금 뭘 써야 하나, LTS와 Valhalla

2026. 10. 3. 13:00·IT
728x90
반응형

자바를 쓰는 팀이 버전을 올릴 때 가장 자주 묻는 질문은 "지금 뭘 써야 하나"다. 2026년 9월 현재 답은 비교적 명확하다. JDK 25가 현행 LTS이고, 다음 LTS는 2027년의 JDK 29다. 그 사이에 나오는 26과 27은 6개월짜리 비-LTS다. 이 글은 현재 릴리스 지형과, 오래 기다려 온 Valhalla가 어디까지 왔는지를 정리한다.

LTS 2년 주기가 자리 잡았다

자바는 2021년부터 2년마다 LTS를 내는 주기를 지키고 있다. 17, 21, 25가 그 결과다. 그 사이 6개월마다 나오는 비-LTS 릴리스는 새 기능을 미리 시험하는 자리다.

실무에서 이 그림이 뜻하는 바는 단순하다. 프로덕션은 LTS로 가고, 비-LTS는 미리 돌려보는 용도로 쓴다. 26이나 27로 프로덕션을 올리면 6개월 뒤 지원이 끊긴다.

문제는 현실이 이 주기를 못 따라간다는 것이다. 2025년 조사에서 JDK 21을 프로덕션에서 쓴다는 응답이 45% 수준이었다. 21이 나온 지 2년이 지난 시점의 수치다. 그 말은 나머지 절반 이상이 17이나 11, 심지어 8에 남아 있다는 뜻이다.

11이나 17에 남아 있다면 무엇을 놓치고 있나

버전을 올리는 것이 귀찮기만 한 일은 아니다. 21 이후 안정화된 기능들이 코드의 모양을 실제로 바꾼다.

레코드(record)는 데이터 전달용 클래스를 한 줄로 줄인다. 봉인 클래스(sealed)는 상속 가능한 하위 타입을 제한해서, 패턴 매칭과 함께 쓰면 컴파일러가 모든 경우를 다뤘는지 검사해 준다. switch 패턴 매칭은 instanceof 뒤에 캐스팅하던 코드를 없앤다.

// 21 이전
if (shape instanceof Circle) {
    Circle c = (Circle) shape;
    return Math.PI * c.radius() * c.radius();
} else if (shape instanceof Rect) {
    Rect r = (Rect) shape;
    return r.w() * r.h();
}
throw new IllegalArgumentException();

// 21 이후 (sealed interface Shape 전제)
return switch (shape) {
    case Circle c -> Math.PI * c.radius() * c.radius();
    case Rect r   -> r.w() * r.h();
};

아래 코드에서 default가 없는데 컴파일이 되는 이유는 Shape가 sealed라서 컴파일러가 하위 타입을 전부 알기 때문이다. 나중에 하위 타입이 추가되면 이 switch가 컴파일 오류를 낸다. 빠뜨린 분기를 사람이 아니라 컴파일러가 찾아준다.

가상 스레드도 21에서 정식이 됐다. 스레드 하나당 OS 스레드를 쓰지 않으므로, 스레드 풀 크기를 고민하던 문제가 상당 부분 사라진다. I/O 대기가 많은 서버에서 효과가 크다.

이 기능들은 문법 설탕이 아니라 버그를 줄이는 장치에 가깝다. 그래서 나는 버전 업그레이드를 "새 기능 써보기"가 아니라 "실수할 여지를 줄이기"로 설명하는 편이 설득에 낫다고 본다.

Valhalla 는 아직 도착하지 않았다

자바에서 가장 오래 기다린 프로젝트를 꼽으라면 Valhalla다. 값 타입(value class)을 도입해서, 객체인데 참조가 아니라 값처럼 동작하게 만드는 것이 목표다.

왜 중요한가. 자바에서 Integer[] 같은 배열은 실제로는 포인터의 배열이고, 각 요소는 힙 여기저기에 흩어져 있다. 순회하면 캐시가 계속 빗나간다. 값 타입이 들어오면 데이터를 연속된 메모리에 펼칠 수 있어서, 수치 연산이 많은 코드의 성능이 달라진다.

2026년 현재 상태는 프리뷰 진입이다. 최종 확정은 JDK 27이나 28이 될 것으로 전망되고, 그러면 실질적으로 쓸 수 있게 되는 것은 2027년 LTS인 29부터다. Vector API가 아직 인큐베이터에 머무는 것도 Valhalla를 기다리기 때문이다. 값 타입이 준비되면 그것을 써서 프리뷰로 승격한다는 계획이 공개돼 있다.

기다린 시간을 생각하면 조심스럽게 볼 필요가 있다. Valhalla는 여러 차례 목표 버전이 밀렸다. 프리뷰에 들어갔다는 것은 분명한 진전이지만, 프리뷰는 최종 형태가 바뀔 수 있다는 뜻이기도 하다. 프로덕션 코드를 값 타입 전제로 설계하는 것은 아직 이르다.

그래서 지금 무엇을 할 것인가

정리하면 판단은 단순하다.

8이나 11에 있다면 21로 올리는 것이 최우선이다. 25가 아니라 21인 이유는, 21은 이미 생태계 지원이 충분히 검증됐고 LTS 기간도 길게 남아 있기 때문이다. 프레임워크와 라이브러리가 21을 요구하기 시작한 지도 꽤 됐다.

이미 21이라면 25로 옮기는 것을 계획한다. 급하지는 않다. 21의 지원은 한동안 계속되고, 25가 주는 것이 극적이지는 않다. 다만 다음 LTS인 29로 한 번에 뛰는 것보다 25를 거치는 편이 검증 부담이 적다.

26이나 27은 프로덕션에 올리지 않는다. 대신 CI에 비-LTS 빌드를 하나 추가해서, 다음 LTS에서 깨질 것을 미리 발견하는 용도로 쓴다. 이 습관이 있으면 LTS 전환이 훨씬 수월해진다.

자바의 릴리스 주기가 빨라진 뒤로 "따라가기 벅차다"는 말이 나오는데, 나는 반대로 본다. 6개월마다 조금씩 바뀌는 편이 3년마다 크게 바뀌는 것보다 낫다. 한 번에 넘어야 할 벽이 낮아졌다.

버전 올리기를 막는 것은 대개 기술이 아니다

자바 버전을 못 올리는 이유를 물어보면 기술적 문제가 나오는 경우는 오히려 적다. 실제로 자주 나오는 것은 이런 것들이다.

빌드와 배포가 특정 버전에 묶여 있다. 오래된 CI 이미지, 특정 JDK만 지원하는 사내 배포 도구, WAS 버전 같은 것들이다. 애플리케이션 코드는 문제없는데 그 주변이 안 따라온다.

검증 비용을 아무도 대지 않는다. 버전 업그레이드는 새 기능을 만들지 않으므로 일정에서 밀린다. 장애가 나면 책임 소재가 분명해지는 반면 성공해도 티가 안 난다.

의존성 중 하나가 발목을 잡는다. 오래된 라이브러리가 리플렉션으로 내부 API를 건드리다가 모듈 시스템에 막히는 식이다.

기술적 해법보다 작게 쪼개는 전략이 통한다. 전체를 한 번에 올리는 대신, 새 서비스부터 최신 LTS로 시작하고 기존 서비스는 교체 주기에 맞춰 옮긴다. 그리고 CI에 다음 LTS 후보로 빌드만 돌려 두면, 실제로 올릴 때 무엇이 깨지는지 미리 알 수 있다. 빌드가 깨진 채로 몇 달을 두면 부채가 쌓이지만, 매일 깨진 것을 보면 고치게 된다.

참고 자료

  • Project Valhalla — OpenJDK — 값 타입의 목표와 현재 진행 상태
  • What's New in Java 26 — JRebel — JDK 26 릴리스 일정과 변경 요약
  • State of Java 2026 — 버전별 채택률과 생태계 현황
  • Java's Multi-Project Evolution: Valhalla, Panama & Amber — Java Code Geeks — Valhalla 와 Vector API 의 의존 관계
728x90
반응형

'IT' 카테고리의 다른 글

쿠버네티스 1.35, 파드 재시작 없이 자원 조정  (0) 2026.10.05
React 20이 없는 이유와 React Compiler  (0) 2026.10.04
Node.js 26의 Temporal, Date를 대체할까  (0) 2026.10.02
Go 1.26 Green Tea GC, 무엇이 빨라졌나  (0) 2026.10.01
Python 3.15와 GIL, 무엇이 실제로 바뀌나  (0) 2026.09.30
'IT' 카테고리의 다른 글
  • 쿠버네티스 1.35, 파드 재시작 없이 자원 조정
  • React 20이 없는 이유와 React Compiler
  • Node.js 26의 Temporal, Date를 대체할까
  • Go 1.26 Green Tea GC, 무엇이 빨라졌나
밍글링글링
밍글링글링
mingling - 밍글링, 밍글밍글링. 코드와 어우러지다. IT/ 프로그래밍/소스
    반응형
    250x250
  • 밍글링글링
    mingling
    밍글링글링
  • 전체
    오늘
    어제
    • 밍글링글링 (451) N
      • Flutter (2)
      • 일상생활 (8)
        • 리뷰 (1)
        • 생활정보 (4)
        • 맛집 (0)
        • 여행 (0)
        • 모든정보 (3)
      • JAVA (126)
        • 개념 (6)
        • 예제 (115)
        • Exception (2)
      • C (1)
        • C (1)
        • C++ (0)
        • C# (0)
      • JS (29)
        • JavaScript (18)
        • JQuery (5)
        • AJax (0)
        • NODE.JS (6)
        • Angular.JS 2.0 (0)
      • WEB (87)
        • HTML (6)
        • CSS (61)
        • JSP (20)
        • JSTL (0)
      • FrameWork (8)
        • Spring (8)
        • BootStrap (0)
        • MyBATIS (0)
        • JUnit (0)
      • 외부 라이브러리 (5)
      • 공유 소스 관리 (5)
        • Git (5)
        • SVN (0)
      • 빅데이터 프로그래밍 (37)
        • Python (37)
        • R Programming (0)
      • DB (7)
        • ORACLE (0)
        • MySql (6)
      • Development Tools (7)
        • StarUML (0)
        • eXERD (0)
        • Eclipse (4)
      • SKILL (6)
        • Migration (0)
        • Security (6)
      • MicroSoft (0)
        • Excel (0)
        • Word (0)
      • Android (0)
      • Server (21)
        • Ubuntu (5)
        • Linux (15)
      • IOS (0)
      • XML (0)
      • 미디어 (0)
      • 공지사항 (3)
      • NETWORK (1)
      • 게임 (4)
        • 피파 (1)
        • 리니지M (0)
        • 배틀그라운드 (1)
        • 듀랑고 (2)
      • 세상 이슈 (6)
      • 일렉트론 (0)
      • 대회 소식 (4)
      • 업무 (2)
      • Express, Vue (6)
      • docker (11)
      • svelte (3)
      • 블록체인 (1)
      • IT (54) N
      • Rust (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    러스트
    SSL 인증서
    Node
    svelte
    프런트엔드
    spring java
    브라우저 자동화
    css table
    nginx
    ssl 인증서 발급
    java casting
    오류
    리눅스 설치
    css tb
    jsp include
    mysql db
    Rust lang
    자바 for문
    servlet class
    proxy pass
    자바 exception
    rust linux
    nginx ssl 설정
    티스토리 자동화
    자바 생성자
    jsp parameter
    ubuntu
    제미나이
    nginx ssl 적용
    gitlab 설치
    AI 코딩 에이전트
    클론코딩
    React Compiler
    vue cli
    에디터 팁
    css perspective
    vscode
    Extension Bisect
    Java Array
    자바 배열
    css transition
    API 설계
    자바 객체 지향
    docker
    AI 반도체
    자바 클래스
    VS Code 팁
    lang rust
    vue 설치
    css float
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
밍글링글링
자바 버전 지금 뭘 써야 하나, LTS와 Valhalla
상단으로

티스토리툴바