java.base

2024. 7. 9. 11:39High Level Programming Language/Reflection

📦 Java의 java.base 모듈

Java 9부터 도입된 JPMS(Java Platform Module System)는 자바 플랫폼을 모듈 단위로 구성할 수 있게 해주는 강력한 시스템입니다. 그 중심에는 언제나 존재하는, 절대 빠질 수 없는 핵심 모듈, 바로 java.base가 있습니다.

 

🧩 1. java.base 모듈이란?

java.base는 Java 플랫폼의 핵심 클래스들을 모아놓은 기본 모듈입니다.

 

모든 자바 애플리케이션은 암묵적으로 이 모듈에 의존합니다.

즉, module-info.javarequires java.base;를 쓰지 않아도 자동 포함됩니다.

 

📚 2. 포함된 주요 패키지들

다음은 java.base에 포함된 대표적인 패키지와 클래스들입니다:

패키지 대표 클래스 설명
java.lang Object, String, System, Math 모든 자바 프로그램의 기본 클래스
java.util List, Map, Collections, Optional 자료구조, 유틸리티 컬렉션
java.io InputStream, Reader, File, BufferedReader 파일, 스트림, 콘솔 입출력
java.nio Path, ByteBuffer, Files NIO 파일시스템 및 버퍼
java.net URI, URL, Socket, HttpURLConnection 네트워크 클래스
java.time LocalDate, Instant, Duration Java 8의 날짜/시간 API
java.math BigInteger, BigDecimal 고정밀 수학 계산
java.util.concurrent Executor, Future, AtomicInteger 멀티스레딩 및 동시성 도구
java.lang.reflect Field, Method, Constructor 리플렉션 API

👉 이 외에도 JVM, 보안, 스트림, 직렬화 관련 패키지도 포함됩니다.

 

🧱 3. java.base의 특수한 위치

🎯 모듈 의존성 트리의 루트

  • java.base는 모든 다른 Java 모듈(java.sql, java.xml, java.desktop, jdk.httpserver 등)의 최상위 의존 대상입니다.
  • 다른 모듈들은 requires java.base;명시적으로 선언합니다.

🔒 강력한 캡슐화

  • Java 9 이후, 모듈은 자신의 패키지 공개 여부를 제어할 수 있습니다.
  • java.base는 대부분의 패키지를 외부에서 리플렉션으로 접근하지 못하도록 디폴트로 닫혀 있습니다.

예를 들어, 아래와 같은 코드는 Java 17에서 예외가 발생합니다:

Field f = BufferedReader.class.getDeclaredField("cb");
f.setAccessible(true); // ❌ InaccessibleObjectException 발생

 

🛠 4. 왜 --add-opens가 필요한가?

Java 8까지는 JVM이 클래스의 모든 필드에 리플렉션으로 자유롭게 접근할 수 있었습니다.
하지만 Java 9 이후 모듈 시스템은 이를 차단합니다.

 

📌 해결법:

JVM 실행 시 다음 인자를 추가해야 합니다:

--add-opens java.base/java.io=ALL-UNNAMED

 

 

📖 의미 분석:

구성 요소 의미
java.base 대상 모듈 (열릴 모듈)
java.io 열어줄 패키지
ALL-UNNAMED 이름 없는 모듈 (= 일반 자바 클래스들)에게 허용

 

🧪 예제: 모듈 접근 없이 실행하면

BufferedReader reader = new BufferedReader(new StringReader("hi"));
Field cbField = BufferedReader.class.getDeclaredField("cb");
cbField.setAccessible(true); // ❌ Java 17+에서는 오류 발생

예외 메시지:

java.lang.reflect.InaccessibleObjectException:
Unable to make field private char[] java.io.BufferedReader.cb accessible:
module java.base does not "opens java.io" to unnamed module

 

🧮 5. java.base는 어떻게 정의되어 있는가?

$JAVA_HOME/jmods/java.base.jmod 또는 JDK 내부의 java.base는 다음처럼 정의되어 있습니다:

module java.base {
    exports java.lang;
    exports java.util;
    exports java.io;
    exports java.nio;
    ...
}

그러나 exports ≠ opens입니다.

  • exports: 컴파일러 수준의 접근 허용 (public만 보임)
  • opens: 리플렉션을 통한 런타임 접근 허용

java.base는 대부분의 패키지를 exports만 하고, opens는 거의 하지 않습니다. 따라서 --add-opens를 써야 합니다.

 

✅ 요약 정리

항목 설명
java.base란? 자바 플랫폼의 핵심 모듈, 모든 자바 프로그램이 자동 의존
포함 내용 java.lang, java.util, java.io, java.time, java.nio
자동 포함 여부 module-info.java 없이도 자동으로 의존
캡슐화 수준 매우 강함, 리플렉션 시 예외 발생 가능
해결법 JVM 실행 시 --add-opens java.base/패키지=ALL-UNNAMED 설정
역할 Java 플랫폼의 기초 기능과 API를 제공하는 루트 모듈

 

📌 마무리

java.base는 마치 자바 프로그램의 뼈대와 같은 모듈입니다.
모든 자바 애플리케이션이 이 모듈 없이는 존재할 수 없으며, 리플렉션 등의 고급 기능을 사용할 경우에는 모듈 시스템의 보안 정책을 우회하는 방법(--add-opens)을 알아두어야 합니다.