Java 9의 모듈성 : Project Jigsaw, Penrose 및 OSGi로 쌓기

이 기사는 Java 9에서 Java 기술을보다 모듈화하기위한 제안, 사양 및 플랫폼에 대한 개요를 제공합니다.보다 모듈화 된 Java 아키텍처의 필요성에 기여하는 요소에 대해 논의하고 제안 된 솔루션을 간략하게 설명하고 비교합니다. Java 개발에 대한 잠재적 영향을 포함하여 Java 9 용으로 계획된 세 가지 모듈성 업데이트를 소개합니다.

Java 모듈성이 필요한 이유는 무엇입니까?

모듈화 는 일반적인 개념입니다. 소프트웨어에서는 단일 모 놀리 식 디자인이 아닌 여러 고유 모듈로 프로그램 또는 컴퓨팅 시스템을 작성하고 구현하는 데 적용됩니다. 그런 다음 표준화 된 인터페이스를 사용하여 모듈이 통신 할 수 있도록합니다. 소프트웨어 구성 환경을 별개의 모듈로 분할하면 결합을 최소화하고 애플리케이션 개발을 최적화하며 시스템 복잡성을 줄이는 데 도움이됩니다.

모듈화를 통해 프로그래머는 특정 스프린트 또는 프로젝트 중에 기능 테스트를 분리하고 병렬 개발 작업에 참여할 수 있습니다. 이는 전체 소프트웨어 개발 라이프 사이클에서 효율성을 증가시킵니다.

정품 모듈의 일부 특성화 속성은 다음과 같습니다.

  • 자율 배포 단위 (느슨한 결합)
  • 일관되고 고유 한 ID (모듈 ID 및 버전)
  • 쉽게 식별되고 발견 된 요구 사항 및 종속성 (표준 컴파일 시간 및 배포 기능 및 메타 정보)
  • 개방적이고 이해하기 쉬운 인터페이스 (통신 계약)
  • 숨겨진 구현 세부 정보 (캡슐화)

모듈을 효율적으로 처리하도록 구축 된 시스템은 다음을 수행해야합니다.

  • 컴파일 타임에 모듈화 및 종속성 검색 지원
  • 시스템 다운 타임없이 손쉬운 배포 및 재배포를 지원하는 런타임 환경에서 모듈 실행
  • 명확하고 강력한 실행 수명주기 구현
  • 간편한 등록 및 모듈 검색을위한 기능 제공

객체 지향, 구성 요소 지향 및 서비스 지향 솔루션은 모두 순수한 모듈화를 가능하게하려고 시도했습니다. 그러나 각 솔루션에는 모듈 식 완벽을 달성하지 못하는 고유 한 단점이 있습니다. 간단히 고려해 봅시다.

모듈 식 구조로서의 Java 클래스 및 객체

Java의 객체 지향 특성이 모듈성 요구 사항을 충족하지 않습니까? 결국 Java를 사용한 객체 지향 프로그래밍은 고유성, 데이터 캡슐화 및 느슨한 결합을 강조하고 때로는 강제합니다. 이러한 점이 좋은 출발점이기는하지만 Java의 객체 지향 프레임 워크에서 충족 하지 않는 모듈성 요구 사항에 유의 하십시오. 객체 수준의 ID는 신뢰할 수 없습니다. 인터페이스는 버전이 지정되지 않으며 클래스는 배포 수준에서 고유하지 않습니다. 느슨한 결합은 모범 사례이지만 확실히 적용되지는 않습니다.

타사 종속성이 너무 쉽게 오용되는 경우 Java에서 클래스를 재사용하기가 어렵습니다. Maven과 같은 컴파일 타임 도구는 이러한 단점을 해결하려고합니다. 종속성 주입 및 제어 역전과 같은 사후 언어 규칙 및 구조는 개발자가 런타임 환경을 제어하려는 시도에 도움이되며, 특히 엄격한 규율과 함께 사용되는 경우 성공할 수 있습니다. 안타깝게도 이러한 상황은 독점적 인 프레임 워크 규칙 및 구성에 따라 모듈 식 환경을 생성해야하는 번거 로움을 남깁니다.

Java는 모듈 식 컴파일 타임 및 배포 타임 메커니즘을 생성하기위한 수단으로 패키지 네임 스페이스와 범위 가시성을 조합에 추가합니다. 그러나 이러한 언어 기능은 내가 설명 하겠지만 쉽게 회피 할 수 있습니다.

모듈 식 솔루션으로서의 패키지

패키지는 Java 프로그래밍 환경에 추상화 수준을 추가하려고합니다. 고유 한 코딩 네임 스페이스 및 구성 컨텍스트를위한 기능을 제공합니다. 하지만 안타깝게도 패키지 규칙은 쉽게 우회되어 위험한 컴파일 타임 커플 링 환경으로 이어지는 경우가 많습니다.

현재 Java의 모듈화 상태 (OSGi는 제외하고, 곧 설명하겠습니다)는 대부분의 경우 패키지 네임 스페이스, JavaBeans 규칙 및 Spring에서 발견되는 독점 프레임 워크 구성을 사용하여 달성됩니다.

JAR 파일은 모듈 식으로 충분하지 않습니까?

JAR 파일과 이들이 작동하는 배포 환경은 다른 방법으로 사용할 수있는 많은 레거시 배포 규칙에서 크게 향상됩니다. 그러나 JAR 파일에는 .jar 매니페스트에 숨겨져있는 거의 사용되지 않는 버전 번호를 제외하고는 고유 한 고유성이 없습니다. JAR 파일 및 선택적 매니페스트는 Java 런타임 환경 내에서 모듈화 규칙으로 사용되지 않습니다. 따라서 파일에있는 클래스의 패키지 이름과 클래스 경로에 대한 참여는 런타임 환경에 모듈성을 제공하는 JAR 구조의 유일한 부분입니다.

간단히 말해서 JAR은 모듈화에 좋은 시도이지만 진정한 모듈 식 환경에 대한 모든 요구 사항을 충족하지는 않습니다. Spring 및 OSGi와 같은 프레임 워크 및 플랫폼은 JAR 사양에 대한 패턴 및 개선 사항을 사용하여 매우 유능한 모듈 식 시스템을 구축하기위한 환경을 제공합니다. 그러나 시간이 지남에 따라 이러한 도구조차도 JAR 사양 JAR 지옥의 매우 불행한 부작용에 굴복합니다!

Classpath / JAR 지옥

Java 런타임 환경이 임의의 복잡한 JAR로드 메커니즘을 허용하는 경우 개발자는 이들이 클래스 경로 지옥 또는 JAR 지옥 에 있음을 알고 있습니다. 여러 구성으로 인해이 상태가 발생할 수 있습니다.

먼저 Java 애플리케이션 개발자가 애플리케이션의 업데이트 된 버전을 제공하고 이전 버전과 정확히 동일한 이름으로 JAR 파일에 패키지화 한 상황을 고려하십시오. Java 런타임 환경은 올바른 JAR 파일을 판별하기위한 유효성 검증 기능을 제공하지 않습니다. 런타임 환경은 처음 찾거나 여러 클래스 경로 규칙 중 하나를 충족하는 JAR 파일에서 클래스를로드합니다. 이로 인해 기껏해야 예기치 않은 동작이 발생합니다.

두 개 이상의 애플리케이션 또는 프로세스가 서로 다른 버전의 타사 라이브러리에 의존하는 JAR 지옥의 또 다른 인스턴스가 발생합니다. 표준 클래스 로딩 기능을 사용하면 런타임에 하나의 타사 라이브러리 버전 만 사용할 수 있으므로 하나 이상의 애플리케이션 또는 프로세스에서 오류가 발생합니다.

모든 기능을 갖춘 효율적인 Java 모듈 시스템은 코드를 구별되고 이해하기 쉬우 며 느슨하게 결합 된 모듈로 쉽게 분리 할 수 ​​있어야합니다. 종속성을 명확하게 지정하고 엄격하게 적용해야합니다. 다른 모듈에 부정적인 영향을주지 않고 모듈을 업그레이드 할 수있는 시설을 사용할 수 있어야합니다. 모듈 식 런타임 환경은 특정 도메인 또는 수직 시장에 특정한 구성을 가능하게하여 환경의 시작 시간과 시스템 공간을 줄여야합니다.

Java 용 모듈화 솔루션

지금까지 언급 한 모듈성 기능과 함께 최근의 노력으로 몇 가지가 더 추가되었습니다. 다음 기능은 성능을 최적화하고 런타임 환경을 확장하기위한 것입니다.

  • 세분화 된 소스 코드 : 소스 코드는 고유 한 캐시 된 세그먼트로 분리되며 각 세그먼트에는 특정 유형의 컴파일 된 코드가 포함됩니다. 목표에는 가비지 스윕, 증분 빌드 및 더 나은 메모리 관리 중에 비 메소드 코드 건너 뛰기가 포함됩니다.
  • 빌드 시간 적용 : 네임 스페이스, 버전 관리, 종속성 등을 적용하는 언어 구성입니다.
  • 배포 시설 : 모바일 장치 환경과 같은 특정 요구 사항에 따라 확장 된 런타임 환경 배포를 지원합니다.

이러한 기능을 용이하게하기 위해 많은 모듈성 사양 및 프레임 워크가 모색되었으며 최근 몇 가지가 Java 9 제안에서 최상위에 올랐습니다. Java 모듈성 제안에 대한 개요는 다음과 같습니다.

JSR (Java 사양 요청) 277

현재 비활성은 Java Module System 인 JSR (Java Specification Request) 277입니다. 이 사양은 OSGi와 동일한 영역의 대부분을 다루었습니다. OSGi와 마찬가지로 JSR 277은 런타임 수정 및 / 또는 무결성 검사에 대한 희소 지원을 통해 모듈의 검색,로드 및 일관성도 정의합니다.

JSR 277의 단점은 다음과 같습니다.

  • 모듈 / 번들의 동적 로딩 및 언 로딩 없음
  • 클래스 공간 고유성에 대한 런타임 검사 없음

OSGi (Open Service Gateway Initiative)

1998 년 11 월 OSGI Alliance에서 소개 한 OSGI 플랫폼은 Java의 공식 표준 질문에 가장 널리 사용되는 모듈 식 답변입니다. 현재 릴리스 6에서 OSGi 사양은 특히 최근에 널리 수용되고 사용됩니다.

본질적으로 OSGi는 모듈, 서비스, 배치 가능한 번들 등의 형태로 완전하고 동적 인 컴포넌트 모델을 구현하는 Java 프로그래밍 언어를위한 모듈 형 시스템이자 서비스 플랫폼입니다.

OSGI 아키텍처의 기본 계층은 다음과 같습니다.

  • 실행 환경 : 번들이 실행되는 Java 환경 (예 : Java EE 또는 Java SE)입니다.
  • Module : OSGi 프레임 워크가 번들의 모듈 측면을 처리하는 곳입니다. 번들 메타 데이터는 여기에서 처리됩니다.
  • 수명주기 : 번들 초기화, 시작 및 중지가 여기에서 발생합니다.
  • 서비스 레지스트리 : 번들은 발견 할 다른 번들에 대한 서비스를 나열합니다.

OSGi의 가장 큰 단점 중 하나는 기본 패키지 설치를위한 공식 메커니즘이 없다는 것입니다.

JSR 291

JSR 291은 OSGi를 기반으로하는 Java SE 용 동적 구성 요소 프레임 워크이며 현재 개발의 마지막 단계에 있습니다. 이 노력은 JSR 232에 의해 Java 모바일 환경에서 수행 된 것과 같이 OSGi를 주류 Java로 가져 오는 데 초점을 맞추고 있습니다.

JSR 294

JSR 294는 메타 모듈 시스템을 정의하고 플러그 형 모듈 (버전, 종속성, 제한 등)의 실제 구현을 외부 공급자에게 위임합니다. 이 사양은 모듈화를 용이하게하기 위해 "수퍼 패키지"및 계층 적으로 관련된 모듈과 같은 언어 확장을 소개합니다. 엄격한 캡슐화 및 고유 한 컴파일 단위도 사양의 초점의 일부입니다. JSR 294는 현재 휴면 상태입니다.

프로젝트 퍼즐

Project Jigsaw는 Java 9의 모듈화 가능성이 가장 높은 후보입니다. Jigsaw는 언어 구조와 환경 구성을 사용하여 Java SE 용 확장 가능한 모듈 시스템을 정의하려고합니다. Jigsaw의 주요 목표는 다음과 같습니다.

  • Java SE 런타임 및 JDK를 소형 장치로 매우 쉽게 확장 할 수 있습니다.
  • 내부 JDK API에 대한 액세스를 금지하고 SecurityManager.checkPackageAccess메소드를 시행 및 개선하여 Java SE 및 JDK의 보안을 개선합니다 .
  • 기존 코드의 최적화를 통해 애플리케이션 성능을 개선하고 미리보기 프로그램 최적화 기술을 촉진합니다.
  • 개발자가 제공 한 모듈과 모듈 식 JDK에서 라이브러리와 애플리케이션을 구성 할 수 있도록하여 Java SE 내에서 애플리케이션 개발을 단순화합니다.
  • 유한 한 버전 제약 세트 요구 및 시행

JEP (Java Enhancement Proposal) 200

2014 년 7 월에 작성된 Java Enhancement Proposal 200은 JDK에 대한 모듈 식 구조를 정의하려고합니다. JEP 200은 Java 8 Compact Profiles에 따라 JDK를 컴파일 타임, 빌드 타임, 배포 타임에 결합 할 수있는 모듈 세트로 쉽게 분할하기 위해 Jigsaw 프레임 워크를 기반으로합니다. 그런 다음 이러한 모듈 조합을 Jigsaw 호환 모듈로 구성된 축소 된 런타임 환경으로 배포 할 수 있습니다.

201 년 9 월

JEP 201은 Jigsaw를 기반으로 JDK 소스 코드를 모듈로 재구성하려고합니다. 이러한 모듈은 모듈 경계를 적용하는 향상된 빌드 시스템에 의해 별개의 단위로 컴파일 될 수 있습니다. JEP 201은 소스 코드 트리의 최상위 레벨에서 모듈 경계를 강조하는 JDK 전체에 걸쳐 소스 코드 재구성 체계를 제안합니다.

Penrose

Penrose는 Jigsaw와 OSGi 간의 상호 운용성을 관리합니다. 특히, 수정 된 커널에서 실행되는 번들이 Jigsaw 모듈을 활용하기 위해 OSGi 마이크로 커널을 수정하는 기능을 용이하게합니다. 모듈을 설명하기 위해 JSON을 사용합니다.

Java 9 계획

Java 9는 Java의 고유 한 주요 릴리스입니다. 이 제품을 독특하게 만드는 것은 전체 JDK에 걸쳐 모듈 식 구성 요소와 세그먼트를 도입 한 것입니다 . 모듈화를 지원하는 주요 기능은 다음과 같습니다.

  • 모듈 식 소스 코드 : Java 9에서 JRE와 JDK는 상호 운용 가능한 모듈로 재구성됩니다. 이를 통해 소형 장치에서 실행할 수있는 확장 가능한 런타임을 생성 할 수 있습니다.
  • 세분화 된 코드 캐시 : 엄격하게 모듈화 된 기능은 아니지만 Java 9의 새로운 세분화 된 코드 캐시는 모듈화 정신을 따르고 동일한 이점을 누릴 수 있습니다. 새로운 코드 캐시는 자주 액세스하는 코드 세그먼트를 네이티브 코드로 컴파일하고 최적화 된 조회 및 향후 실행을 위해 저장하는 지능적인 결정을 내립니다. 힙은 또한 3 개의 개별 단위로 분할됩니다. 캐시에 영구적으로 저장되는 비 메소드 코드; 잠재적으로 긴 수명주기를 가진 코드 ( "프로파일되지 않은 코드"라고 함) 일시적인 코드 ( "프로파일 된 코드"라고 함).
  • 빌드 시간 적용 : 빌드 시스템은 JEP 201을 통해 모듈 경계를 컴파일하고 적용하기 위해 향상됩니다.
  • 배포 기능 : 도구는 Jigsaw 프로젝트 내에서 제공되어 배포시 모듈 경계, 제약 조건 및 종속성을 지원합니다.

Java 9 조기 액세스 릴리스

Java 9의 정확한 릴리스 날짜는 미스터리로 남아 있지만 Java.net에서 조기 액세스 릴리스를 다운로드 할 수 있습니다.

결론적으로

이 기사는 Java 9의 모듈성에 대한 전망을 포함하여 Java 플랫폼 내의 모듈성에 대한 개요였습니다. 클래스 경로 지옥과 같은 오랜 문제가 더 모듈화 된 Java 아키텍처의 필요성에 어떻게 기여하는지 설명하고 가장 최근의 새로운 모듈성에 대해 논의했습니다. Java에 제안 된 기능. 그런 다음 OSGi 및 Project Jigsaw를 포함한 각 Java 모듈성 제안 또는 플랫폼을 설명하고 맥락화했습니다.

보다 모듈화 된 Java 아키텍처에 대한 필요성은 분명합니다. OSGi가 매우 가까워졌지만 현재의 시도는 부족했습니다. Java 9 릴리스의 경우 Project Jigsaw와 OSGi는 Java 용 모듈 식 공간의 주요 플레이어가 될 것이며 Penrose는 이들 사이에 접착제를 제공 할 수 있습니다.

이 이야기, "자바의 모듈성 : 프로젝트 Jigsaw, Penrose 및 OSGi로 쌓기"는 원래 JavaWorld에 의해 출판되었습니다.