
1. Project Jigsaw: 왜 자바는 '모듈'을 선택했는가?
Java 9의 탄생과 함께 등장한 모듈 시스템(JPMS: Java Platform Module System), 일명 'Project Jigsaw'는 자바 언어의 구조를 근본적으로 뒤바꾼 혁명적인 변화입니다. 그동안 자바는 거대한 rt.jar 파일 하나에 모든 표준 라이브러리를 담아 배포해 왔습니다. 이로 인해 아주 작은 애플리케이션을 구동할 때도 수백 메가바이트의 런타임 환경이 필요했고, 이는 클라우드 네이티브 환경과 마이크로서비스 아키텍처(MSA) 시대로 접어들며 큰 약점이 되었습니다. Project Jigsaw는 자바 런타임 자체를 쪼개고, 개발자가 작성하는 코드 역시 '모듈'이라는 단위로 캡슐화할 수 있게 하여 보안성과 효율성을 극대화하는 것을 목표로 합니다.
2. 모듈 시스템의 핵심 개념과 구조
모듈은 패키지의 한 단계 상위 개념입니다. 관련 있는 패키지들을 묶고, 그 중 외부로 노출할 패키지와 숨길 패키지를 module-info.java 파일을 통해 명시적으로 정의합니다.
| 주요 키워드 | 기능 설명 |
|---|---|
| exports | 외부 모듈에서 접근할 수 있도록 특정 패키지를 공개합니다. |
| requires | 현재 모듈이 의존하고 있는 다른 모듈을 명시합니다. |
| opens | 리플렉션(Reflection)을 통해서만 접근 가능한 패키지를 지정합니다. |
| provides / with | 서비스 프로바이더 인터페이스(SPI)를 구현하고 제공할 때 사용합니다. |
3. 기존 방식(Classpath) vs 모듈 방식(Modulepath)
모듈 시스템은 기존 자바 개발의 고질적인 문제였던 'Jar Hell(의존성 충돌)' 문제를 해결합니다.
| 비교 항목 | 기존 Classpath (Java 8 이전) | 모듈 방식 (Java 9 이후) |
|---|---|---|
| 캡슐화 | public 클래스는 어디서든 접근 가능 | exports 되지 않은 패키지는 접근 불가 |
| 의존성 확인 | 런타임에 클래스를 찾지 못하면 에러 발생 | 컴파일 타임에 누락된 모듈 확인 가능 |
| 배포 크기 | 전체 JRE가 포함되어 크기가 큼 | jlink를 통해 필요한 모듈만 포함 (경량화) |
| 성능 | 모든 클래스를 검색해야 하므로 느림 | 모듈 그래프를 통해 빠른 로딩 가능 |
4. Sample Example: 간단한 모듈 만들기
모듈 시스템을 적용하기 위해서는 프로젝트 루트에 module-info.java가 반드시 존재해야 합니다.
Step 1: 모듈 정의 (com.example.hello)
// src/com.example.hello/module-info.java
module com.example.hello {
exports com.example.hello.api; // 외부에서 사용할 수 있도록 API 패키지 노출
}
Step 2: 모듈 사용 (com.example.main)
// src/com.example.main/module-info.java
module com.example.main {
requires com.example.hello; // 위에서 만든 모듈을 의존성에 추가
}
5. 결론: 왜 지금 모듈 시스템을 알아야 하는가?
단순히 최신 버전을 쓰는 것을 넘어, jlink 도구를 사용하여 커스텀 런타임 이미지를 생성하면 Docker 컨테이너 크기를 수십 메가바이트 단위로 줄일 수 있습니다. 이는 클라우드 비용 절감과 직결됩니다. 또한 강력한 캡슐화는 내부 구현 로직을 완벽하게 보호하여 대규모 협업 프로젝트에서 예기치 못한 결합도를 낮춰줍니다.
6. 참고 문헌 및 출처
- OpenJDK Project Jigsaw: openjdk.org/projects/jigsaw
- Oracle Java 9 Documentation: Understanding the Java Module System
- Effective Java 3rd Edition (Chapter 2: Creating and Destroying Objects)
'Language > Java' 카테고리의 다른 글
| [JAVA] Java 11 : LTS의 시작과 새로운 HTTP 클라이언트 전환점 (0) | 2026.01.23 |
|---|---|
| [JAVA] Java 10 var 키워드 완벽 가이드 : 지역 변수 타입 추론의 마법 (0) | 2026.01.23 |
| [JAVA] Method Reference 완벽 가이드 : 코드를 예술로 만드는 방법 (0) | 2026.01.23 |
| [JAVA] Optional<T> Class를 사용하는 이유는? Null과의 전쟁을 끝내는 법 (0) | 2026.01.22 |
| [JAVA] Java Stream 중간 연산과 최종 연산의 차이점 완벽 분석 (0) | 2026.01.22 |