14장
1. 모듈 시스템의 필요성
자바 9 이전까지는 모듈화된 소프트웨어 프로젝트를 만드는 데 한계가 있었다. 자바는 클래스, 패키지, JAR 세 가지 수준의 코드 그룹화를 제공했다. 클래스와 관련해 자바는 접근 제어자와 캡슐화를 지원했지만, JAR 수준에서는 캡슐화를 거의 지원하지 않았다. 클래스를 모두 컴파일한 다음 한 개의 평범한 JAR 파일에 넣고 클래스 경로에 이 JAR 파일을 추가해야 했다. 그리고 JVM이 동적으로 클래스 경로에 정의된 클래스를 필요할 때 읽었다. 이 방법은 문제가 많았다.첫 번째로 클래스 경로에는 같은 클래스를 구준하는 버전 개념이 없었다. 클래스 경로에 같은 라이브러리가 두 개 존재할 때 어떤 일이 일어날지 예측할 수 없었다. 두 번째로 클래스 경로가 명시적인 의존성을 지원하지 않았다. 각각의 JAR 안에 있는 모든 클래스는 classes라는 한 주머니로 합쳐졌다. 한 JAR가 다른 JAR에 포함된 클래스 집합을 사용할 때 어떤 일이 일어나는지 파악하기가 어려웠다. JDK 자체에도 문제가 있었다. JDK에 많은 기술이 추가되었다가 사장되었지만, 애플리케이션에서 실제로 사용하는지와 상관없이 JDK에 포함되어야 했다. 자바의 낮은 캡슐화 지원으로 JDK 라이브러리의 내부 API가 외부에 공개되기도 했다. 호환성을 깨지 않고는 관련 API를 변경할 수 없었기 때문에 이 문제들은 오랫동안 개발자들을 괴롭혔다. 결국 JDK에서 필요한 부분만 골라 사용하고 클래스 경로를 쉽게 유추할 수 있으며 플랫폼을 진화시킬 수 있는 강력한 캡슐화를 제공할 새로운 건축 구조, 모듈의 필요성이 제기되었다.
2. 자바 모듈
자바 8은 모듈이라는 새로운 자바 프로그램 구조 단위를 제공한다. 모듈(module)은 module이라는 새 키워드에 이름과 바디를 추가해서 정의한다. 모듈 디스크립터(module descriptor)는 module-info.java라는 특별한 파일에 저장된다. 자바 9에서는 모듈 간 상호작용을 위해 export, requires를 제공한다. 기본적으로 모듈 시스템은 화이트 리스트 기법을 이용해 강력한 캡슐화를 제공한다. 다른 모듈에서 기능을 사용하기 위해선 명시적으로 지정해야 한다. exports는 다른 모듈에서 사용할 수 있도록 특정 패키지를 공개 형식으로 만든다. 또한 기본적으로 모든 모듈은 java.base라는 플랫폼 모듈에 의존한다. 플랫폼 모듈은 net, io, util 등 자바 메인 패키지를 포함한다. 따라서 requires는 java.base를 제외한 모듈을 import해서 의존하고 있는 모듈을 지정한다.

모듈 시스템의 등장으로 .class 파일의 실행 옵션이 추가되었다.
--module-path: 어떤 모듈을 로드할 수 있는지 지정
--module: 실행할 메인 모듈과 클래스 지정
프로젝트를 설정하고 모듈을 정의한 후에는 빌드 도구를 이용해 프로젝트를 컴파일할 수 있다. 각 모듈은 독립적으로 컴파일되므로 자체적으로 각각 한 개의 프로젝트다. 전체 프로젝트의 빌드를 조정할 수 있도록 빌드 도구에 모듈을 추가할 수 있다. 만일 모듈화가 되어있지 않은 외부 라이브러리를 사용한다면 자바는 JAR를 자동 모듈이라는 형태로 적절하게 변환한다.
참고 자료
모던 자바 인 액션 - 한빛미디어
Last updated