2024. 7. 9. 11:39ㆍHigh Level Programming Language/Reflection
📦 Java의 java.base
모듈
Java 9부터 도입된 JPMS(Java Platform Module System)는 자바 플랫폼을 모듈 단위로 구성할 수 있게 해주는 강력한 시스템입니다. 그 중심에는 언제나 존재하는, 절대 빠질 수 없는 핵심 모듈, 바로 java.base
가 있습니다.
🧩 1. java.base
모듈이란?
java.base
는 Java 플랫폼의 핵심 클래스들을 모아놓은 기본 모듈입니다.
✅ 모든 자바 애플리케이션은 암묵적으로 이 모듈에 의존합니다.
즉, module-info.java
에 requires 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
)을 알아두어야 합니다.
'High Level Programming Language > Reflection' 카테고리의 다른 글
String 클래스가 구현하는 Comparable<String> 인터페이스 (1) | 2025.06.02 |
---|---|
The Reflection API (0) | 2025.05.28 |
Lesson: Arrays and Enumerated Types (0) | 2024.07.06 |
Lesson: Members[Constructors] (0) | 2024.07.06 |
Lesson: Members[Methods] (0) | 2024.07.06 |