ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java 9. JPMS
    BackEnd/Java 2024. 12. 2. 19:00
    반응형

    자바 플랫폼 모듈 시스템(JPMS)

      JPMS(Java Platform Module System)를 사용하면 코드의 재사용성, 유지보수성, 보안성을 향상시킬 수 있습니다. 모듈은 고유한 이름을 가지며, 관련된 패키지, 리소스, 모듈 디스크립터(module-info.java)로 구성됩니다. JPMS는 빌드 도구 없이도 모듈을 구성할 수 있고, JDK에서 필요한 일부 코드(모듈)만 다운로드할 수 있어 성능과 용량 측면에서 유지보수성을 높일 수 있습니다.

     

    JPMS 주요 특징

    • 신뢰적인 구성: 모듈 간 의존성을 명시적으로 선언할 수 있습니다.
    • 강력한 캡슐화: 모듈 내부의 패키지를 다른 모듈로부터 숨길 수 있습니다.
    • 확장성: 여러 모듈로 나누어 필요한 모듈만 사용할 수 있게 합니다.
    • 성능 향상: 필요한 모듈만 로드하므로, 메모리 사용량을 줄이고 시작 시간을 단축시킵니다.

     

      모듈의 등장으로 모든 코드는 Named Module, Unnamed Module 두 가지로 구분됩니다.

    Named Module

    • 명시적으로 정의된 모듈로, module-info.java 파일을 통해 선언됩니다.
    • 모듈 경로(module path)에 위치하며, 고유한 이름을 가집니다.
    • 의존성과 노출할 패키지를 명시적으로 선언합니다.

     

    Unnamed Module

    • 모듈 시스템 도입 이전의 레거시 코드와의 호환성을 위해 존재합니다.
    • 클래스패스에 있는 모든 클래스와 JAR 파일이 자동으로 unnamed module에 포함됩니다.
    • 이름이 없으며, 모든 패키지를 자동으로 외부에 노출합니다.
    • 모든 다른 모듈을 읽을 수 있지만, named module은 unnamed module을 직접 읽을 수 없습니다.

     

    JPMS 예제

      다음은 com.example.hello 모듈에서 HelloWorld 클래스를 외부로 공개하고(exports), com.example.main 모듈이 사용하는 예제입니다.

     

     

    패키지 구조

    project_root/
    ├── com.example.hello/
    │   ├── src/
    │   │   ├── com/
    │   │   │   └── example/
    │   │   │       └── hello/
    │   │   │           └── HelloWorld.java
    │   │   └── module-info.java
    │   └── com.example.hello.jar
    └── com.example.main/
        ├── src/
        │   ├── com/
        │   │   └── example/
        │   │       └── main/
        │   │           └── Main.java
        │   └── module-info.java
        └── com.example.main.jar

     

    com.example.hello 모듈

    package com.example.hello;
    
    public class HelloWorld {
        public static void sayHello() {
            System.out.println("Hello from com.example.hello module!");
        }
    }
    module com.example.hello {
        exports com.example.hello;
    }

     

    com.example.main 모듈

    package com.example.main;
    
    import com.example.hello.HelloWorld;
    
    public class Main {
        public static void main(String[] args) {
            HelloWorld.sayHello();
        }
    }
    module com.example.main {
        requires com.example.hello;
    }

     

    주요 키워드

    • requires: 컴파일 타임과 런타임 모두에서 의존성이 필요하며, 의존성이 현재 모듈에만 적용됩니다.
    • requires static: 컴파일 타임에만 의존성이 필요하고, 런타임에는 선택적입니다. 주로 특정 기능이 런타임에 항상 필요하지 않은 경우 사용됩니다.
    • requires transitive: 의존성이 현재 모듈과 이를 의존하는 모든 모듈로 전파됩니다.
    • exports: 특정 패키지 전체를 누구에게나 노출합니다.
    • exports ~ to: 특정 패키지를 특정 모듈에만 노출합니다.
    • open: 모듈 전체에 대한 deep reflection을 허가합니다.
    • opens: 특정 패키지에 대한 deep reflection을 허가합니다.
    • opens ~ to: 특정 모듈에만 특정 패키지의 deep reflection을 허가합니다.
    • provides ... with ...: 서비스 구현체들을 등록합니다.
    • uses: 특정 서비스 인터페이스를 사용합니다.

     

    JPMS 적용 이후 변경된 점

    클래스 로더의 구성 변경

    Java 9 이전

    • Bootstrap 클래스 로더: 가장 기본적인 클래스들을 가져옵니다.
    • Extensions 클래스 로더: 추가적인 클래스들을 가져옵니다. 폴더 경로로 구분합니다.
    • System 클래스 로더: classpath에서 찾을 수 있는 클래스들을 가져옵니다.

    Java 9 이후

    • Bootstrap 클래스 로더: java.base 모듈의 클래스들을 가져옵니다.
    • Platform 클래스 로더: Bootstrap 클래스 로더가 처리하지 않는 Java SE Platform or JCP 모듈의 클래스들을 가져옵니다.
    • Application 클래스 로더: Java SE Platform 혹은 JDK 안에 있지 않은 클래스들을 가져옵니다.

    JRE, JDK의 구성 변경

    • rt.jar, tools.jar 등 JRE / JDK 내부에 있던 몇 가지 파일이 삭제되었습니다.
    • JRE / JDK 디렉토리 구성에도 모듈에 맞게 약간의 변화가 있습니다.
    • Modular Image: 필요한 모듈들만 갖고 있는 JRE / JDK를 구성할 수 있습니다.
    반응형

    'BackEnd > Java' 카테고리의 다른 글

    Java 9. 주요 변경 내용 (2)  (0) 2024.12.04
    Java 9. 주요 변경 내용 (1)  (0) 2024.12.03
    Java8. parallelSort  (0) 2022.01.25
    Java8. CompletableFuture  (0) 2022.01.23
    Callable과 Future  (0) 2022.01.23

    댓글

Designed by Tistory.