Java/JVM

[JVM 밑바닥까지 파헤치기] 7-3. 클래스 로딩 매커니즘: 자바 모듈 시스템

noahkim_ 2024. 12. 23. 19:34

저우즈밍 님의 "JVM 밑바닥까지 파헤치기" 책을 정리한 포스팅 입니다


1. JPMS

  • Java 9에서 도입된 모듈 시스템
  • ⚠️ 기존의 Java는 JAR 단위의 클래스패스 기반 구조는 의존성/캡슐화가 느슨하였음
  • ✅ 모듈 단위의 캡슐화, 격리, 의존성 명시 시스템이 도입됨
  • ➡️ 실행 시점에 의존성/가시성을 검증한 후 실행함

 

클래스패스 문제점) 순환 참조

더보기
  • 순환 참조를 감지/차단하지 못함
  • ⚠️ 프로젝트가 커질수록 스파게티 의존성이 되기 쉬움
  • ❌ 초기화 순서 문제 (ClassCircularityError)
  • ❌ 결합도 높아짐

 

클래스패스 문제점) 런타임 오류

더보기
  • 컴파일 타임에 존재했던 의존성이, 런타임 배포시에 빠지면 런타임 에러가 터짐
  •  ClassNotFoundException / NoClassDefFoundError (클래스 없음)
  •  NoSuchMethodError / NoSuchFieldError (클래스 버전 다름)

 

module-info.java

  • 모듈의 경계와 의존성을 정의하는 선언 파일 (메타데이터 역할)
  • ✅ 디렉토리에 .module-info.java가 포함되어 있으면 모듈로 간주됨
키워드 설명
requires
다른 모듈을 참조함
exports
모듈 내부 패키지를 외부에 공개
uses
서비스 인터페이스 사용 명시 (e.g. ServiceLoader)
provides
uses 대상 인터페이스의 구현체 제공 명시
open
리플렉션 허용용 → 특정 패키지를 리플렉션 API에 공개

 

 

코드) module-info.java

더보기
module com.example.app {
    requires java.sql;
    requires com.example.lib;

    exports com.example.api;
    uses com.example.spi.PaymentService;
    provides com.example.spi.PaymentService 
        with com.example.impl.PaymentServiceImpl;
}

 

모듈 경로 (--module-path)

  • 모듈들이 위치하는 디렉토리
  •  기존 클래스패스와 병행 사용 가능

 

코드) --module-path

더보기
java --module-path mods --class-path libs ...

 

2. 모듈화 시대의 클래스 로더

  • Java 9부터 디렉토리 통합 (JAVA_HOME/jre 삭제 → lib/module 통합)
  • 확장 디렉토리 삭제 (lib/ext 삭제)

 

BuiltinClassLoader

  • Java 9 이후 기본 클래스 로더
  • ✅ 기존의 URLClassLoader을 대체함
  • ✅ 모듈 의존성 및 가시성을 고려하여 로드 (모듈 그래프 기반)