[자바] 11. 정리해고 : Java 11에서 사라진 것들 (Java EE·CORBA·Applet)

자바 버전 여행 11편 - Java 11에서 사라진 것들

작성자

카테고리:

* 이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

(자바 버전 여행 ⑪)

자바 8에서 11로 올리다 NoClassDefFoundError를 만나 당황하는 경우가 많다. 대부분 원인은 하나다 — 11에서 조용히 빠진 것들을 아직 쓰고 있어서다. 이번 편은 무엇이 왜 사라졌고, 어떻게 되살리는지 정리한다.

무엇이 사라졌나

빠진 것무엇대안
Java EE 모듈JAXB(java.xml.bind)·JAX-WS 등별도 의존성(jakarta.*)로 추가
CORBA오래된 분산객체 기술사실상 폐기, gRPC 등으로
Applet API브라우저 자바 애플릿웹 표준으로 대체(폐기)
Java Web Startjnlp 배포jpackage 등으로
JavaFXGUI 툴킷OpenJFX로 분리(별도 추가)

핵심은, 이것들이 JDK 밖으로 나갔을 뿐 사라진 게 아니라는 것(CORBA·Applet 제외). JAXB나 JavaFX는 의존성으로 다시 넣으면 그대로 쓴다.

가장 흔한 함정 — JAXB

XML을 객체로 바꾸는 JAXB(javax.xml.bind.*)는 자바 8엔 기본 포함이라 그냥 import해서 썼다. 11에선 빠져서, 같은 코드가 이렇게 터진다.

// Java 8: 잘 됨 / Java 11: 컴파일 또는 실행 시 실패
import javax.xml.bind.JAXBContext;   // package does not exist
...
// java.lang.NoClassDefFoundError: javax/xml/bind/JAXBContext

해결은 간단하다. 빠진 걸 의존성으로 다시 넣으면 된다.

<!-- Maven -->
<dependency>
  <groupId>jakarta.xml.bind</groupId>
  <artifactId>jakarta.xml.bind-api</artifactId>
  <version>4.0.2</version>
</dependency>
<dependency>
  <groupId>org.glassfish.jaxb</groupId>
  <artifactId>jaxb-runtime</artifactId>
  <version>4.0.5</version>
</dependency>

직접 해보기 — 사라진 API 재현하고 되살리기

말로만 들으면 안 와닿는다. 직접 깨뜨렸다가 고쳐 보자. (자바 8과 11 전환은 2편 참고)

  1. 자바 8로 JAXBContext.newInstance(...)를 쓰는 짧은 클래스를 만들어 실행되는 걸 본다.
  2. sdk use java 11...로 11로 바꾼 뒤 같은 코드를 실행 → NoClassDefFoundError 확인.
  3. 위 의존성을 추가(또는 jar를 클래스패스에 넣고)하고 다시 실행 → 되살아나는 걸 확인.
// Convert.java — 객체 하나를 XML로
import javax.xml.bind.*;
import java.io.StringWriter;

public class Convert {
    static class Book { public String title = "Java"; }
    public static void main(String[] args) throws Exception {
        var ctx = JAXBContext.newInstance(Book.class);
        var w = new StringWriter();
        ctx.createMarshaller().marshal(new Book(), w);
        System.out.println(w);
    }
}

실행해 보면 이렇게 나온다.


여기서 조금씩 바꿔 보자.

  • java -version으로 지금 버전을 확인하며 8↔11을 오가 본다.
  • 에러 메시지의 javax/xml/bind 경로를 보고, 왜 이게 ‘패키지가 사라졌다’는 뜻인지 읽어 본다.

한 걸음 더 — 스프링 등 프레임워크는 이런 의존성을 알아서 넣어주는 경우가 많다. 내 프로젝트의 빌드 파일에서 jakarta 관련 의존성을 찾아보자.

✅ 확인 — 11에서 뭐가 왜 빠졌는지, javax.xml.bind 오류를 어떻게 되살리는지 설명할 수 있으면 모듈 C는 끝이다.

왜 뺐나 — JDK 다이어트

Java EE·CORBA 같은 건 이미 다른 생태계(Jakarta EE 등)로 옮겨갔거나 거의 안 쓰였다. JDK에 계속 품고 있는 건 유지보수 부담이라, 모듈 시스템(8편)을 계기로 JDK 밖으로 덜어냈다. ‘표준 라이브러리를 가볍고 집중되게‘가 방향이다. 그래서 사라진 게 아니라, 필요하면 의존성으로 다시 붙이면 된다.

되살리는 법 — 의존성으로

빠진 걸 쓰려면 빌드에 의존성을 추가한다. JAXB는 jakarta.xml.bind + 구현체, JAX-WS도 별도, JavaFX는 OpenJFX로. 즉 ‘삭제’가 아니라 ‘JDK 밖으로 이사‘했을 뿐이다. Maven·Gradle에 좌표만 넣으면 예전처럼 쓴다.

<!-- Maven — 사라진 JAXB 되살리기 -->
<dependency>
  <groupId>jakarta.xml.bind</groupId>
  <artifactId>jakarta.xml.bind-api</artifactId>
  <version>4.0.0</version>
</dependency>

8 → 11 마이그레이션 체크리스트

  • NoClassDefFoundError·ClassNotFound → 빠진 모듈을 의존성으로 추가.
  • sun.* 내부 API 접근 코드를 걷어낸다.
  • --add-modules 임시방편은 지양 — 11엔 그 모듈 자체가 없다.
  • 서드파티 라이브러리를 최신화(구버전이 제거된 API를 참조할 수 있음).
  • 테스트로 확인.

그 다음 — 17로 갈 땐 강한 캡슐화

11까지는 ‘빠진 걸 되살리기’가 핵심이었다면, 17로 갈 땐 강한 캡슐화(16편)라는 더 큰 벽이 있다. 내부 API 접근이 아예 막힌다. 그래서 8→17을 한 번에 하기보다, 11을 경유하며 이 단계들을 나눠 넘는 게 안전하다. 마이그레이션은 계단이지 점프가 아니다 — 이 원칙 하나만 지켜도 사고가 확 준다.

여기까지가 자바 9~11이다. 모듈로 구조를 정리하고, var로 문법을 다듬고, 표준 API를 채우고, 낡은 짐을 덜어냈다. 다음 모듈부터는 자바가 언어 문법 자체를 현대화하는 12~17로 넘어간다. 첫 편은 switch의 부활이다.

🔧 현장에서 — javax가 사라지면 한 줄이 아니라 연쇄로 터진다

실제로 8→21 · Boot 2→3 마이그레이션에서 가장 애를 먹은 게 이 javax.* 제거였다. 한 곳만 고치면 되는 게 아니라, 그 API를 끌어오는 여러 라이브러리의 호환성 문제가 연쇄로 터져 최초 원인이 잘 안 보였다. SpringFox처럼 더는 안 맞는 건 아예 제거하고 OpenAPI 계열로 옮겼다.

교훈 — 제거된 API는 import 한 줄을 고치는 게 아니라 그걸 끌어오는 의존성 전체를 봐야 한다. (전체 과정은 24편)

자주 묻는 질문 (FAQ)

자바 8에서 11로 올렸더니 컴파일이 안 돼요.

JAXB 같은 javax.* API가 11에서 빠져서 그렇습니다. jakarta.xml.bind 의존성을 추가하면 되살아납니다.

제거된 기능은 영영 못 쓰나요?

CORBA·Applet은 사실상 폐기지만, JAXB·JavaFX는 별도 의존성으로 다시 넣어 그대로 씁니다.

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다