엔지니어로 가는 길

Java 9 Modules에 대해 알아보자 본문

프로그래밍/Java

Java 9 Modules에 대해 알아보자

탐p슨 2020. 9. 29. 17:47
728x90

Modules

모듈은 하나 이상의 패키지를 갖는다. 

 

모듈은 full Java app일 수도, a Java Platform API일 수도 또는 a third party API일 수도 있다. 

 

Modules Benefits

1. 군더더기를 제거함으로써 애플리케이션이 알맞은 덩치를 갖게 한다.

프로젝트 Jigsaw(JPMS = Java Platform Module System = Java Jigsaw = Project Jigsaw)의 일환으로 모든 Java Platform API는 별도의 모듈들로 쪼개졌다. 이로써 자신의 어플리케이션에서 필요한(실제로 사용할) 모듈들만 명시할 수 있게(가질 수 있게) 되었다.

 

JPMS가 없는 Java 9 이전에는 모든 Java Platform API들을 애플리케이션에 패키징해야 했다. 왜냐하면 어플

리케이션에서 어떤 클래스를 사용하는지를 확실하게 확인할 공식적인 방법이 없었기 때문이다. 이 때문에

애플리케이션은 불필요하게 크기가 커졌다(사용하지 않는 클래스가 포함되기 때문이다). 이는 모바일 폰이

나 라즈베리 파이 같은 작은 기기에서 문제가 될 수 있다. JPMS는 이 문제를 해결한다.

 

2. 패키지 캡슐화를 가능하게 한다.

 

자바 모듈은 반드시 모듈(A)의 어떤 자바 패키지가 다른 모듈(A를 사용하는 모듈 B)로 exported 될지 (visible 할지) 명시해야만 한다. 다시 말해 공개할 패키지를 명시해야 하고, 명시되지 않은 패키지는 다른 모듈에서 사용할 수 없는 패키지가 된다. 이를 hidden packages 또는 encapsulated packages라 한다. 이는 그 패키지를 갖는 모듈 내부적으로만 사용된다.

 

3. 필요한 모듈이 있는지 없는지를 JVM start-up 타임에 검사한다.

Java 9 이후부터 자바 애플리케이션은 반드시 자바 모듈로 패키징 되어야 한다. 그러므로 어플리케이

션 모듈은 자신이 사용할 다른 모듈(Java API module이나 third party module)을 명시해야 한다. JVM이 구

동될 때 JVM은 애플리케이션 모듈로부터 모듈 dependency graph를 확인하여 이 애플리케이션에서 어떤

모듈을 필요로 하는지 알 수 있다. 다음으로 필요한 모듈들이 있는지를 확인하는데 만약 필요한 모듈을 못

찾으면 JVM은 missing module을 report하고 종료된다.

 

Java 9 이전에는 missing classes(e.g. from a missing JAR file)은 애플리케이션이 실제로 그 missing class

를 사용하려고 시도할 때서야(즉, 런타임의 특정 시점에서야) 비로소 missing임을 알 수 있었다.

 

missing modules를 어플리케이션 startup time에 report 받는 것은 런타임에 받는 것에 비해 매우 큰 이점

을 갖는다.

 

Module Basics

Module name

 

모듈의 이름은 unique 해야 한다. 모듈 이름 규칙은 패키지 이름 규칙과 같다. 하지만 ‘_’는  자바 9 이후부

터 모듈이든 패키지든 클래스든 메소드든 변수든 안 쓰는 게 좋다. Java가 나중에 ‘_’를 사용하고 싶어 하기 때문이다. 가능하면 모듈 이름을 모듈 속 루트 자바 패키지의 이름과 같게 하는 것이 좋다.

 

Directory structure

 

Java 9부터 directory structure는 아래와 같다.

 

-com.module.study
      -com 
            -module
                  -study

 

모듈의 root directory 이름(com.module.study)에 ‘.’는 패키지를 구분짓기 위한 용도가 아니라 그 자체로 모듈의 이름이다.

 

Module Descriptor(module-info.java)

 

자바 모듈마다 module-info.java(‘-’는 원래 자바 클래스 이름으로 불가능)를 가져야 한다. 위치는 그 모듈의

루트 디렉토리이다. 모듈 디스크립터는 이 모듈의 어떤 패키지를 export 하고 이 모듈을 위해 어떤 다른 모

듈이 필요한지(requires)를 명시한다.

 

module com.modules.example {

      exports com.modules.example; // 하위 패키지 포함 안되고 example 하위에 있는 것만

      exports com.modules.example.a.b; // 부모 패키지(a) export 안 하고 export 가능

      requires com.other.modules; // 필요한 모듈 명시하는 방법

}

 

모듈 디스크립터를 작성하는 방법은 위와 같이 'module'이라는 키워드 뒤에 모듈 이름을 적고 클래스를 작성하듯 중괄호로 안에 exports, requires 내용을 적으면 된다. 주의해야 할 점은 어떤 패키지를 exports 했다고 해서 그 패키지의 모든 하위 패키지까지 exports 되는 것은 아니라는 것이다. 또한 모듈 간에 순환 의존 관계를 가질 수 없다. a 패키지가 b 패키지를 requires 하면 b 패키지는 a 패키지를 requires 할 수 없다.

 

Split Packages

 

module test.module1 {

      exports abc.pqr.xyz;


}

module test.module2 {


      exports abc.pqr.xyz;


}

module test.myapp {

      requires test.module1;

      requires test.module2;

}

myapp에서 module1과 module2를 요구하는데 module1과 module2는 같은 패키지를 export 하고 있는 상황이다. 이럴 때 abc.pqr.xyz를 split packages라 한다. 이는 허락되지 않는다.

https://stackoverflow.com/questions/51828014/how-split-packages-are-avoided-in-java-9

참고
http://tutorials.jenkov.com/java/modules.html

728x90
Comments