Java 9 + / Java 11로 마이그레이션 할 때 모듈로 전환해야합니까?


80

현재 Java 8에서 Java 11로 마이그레이션하고 있습니다. 그러나 서비스 업그레이드는 예상보다 덜 고통 스러웠습니다. 기본적으로 build.gradle파일 의 버전 번호 만 변경 하면 서비스가 원활하게 실행되고 있습니다. 우리는 라이브러리와 이러한 라이브러리를 사용하는 (마이크로) 서비스를 업그레이드했습니다. 지금까지 문제 없습니다.

어떤 거기에 필요한 모듈을 실제로 전환하려면? 이것은 불필요한 비용 IMHO를 발생시킬 것입니다. 어떤 제안이나 추가 자료를 읽어 주시면 감사하겠습니다.

명확히하기 위해 모듈을 도입하지 않고 Java 9+ 코드를 사용하면 어떤 결과가 있습니까? 예를 들어 다른 코드와 호환되지 않을 수 있습니까?


10
Java 8에서 이미 직면 한 것과 같은 위험이 있습니다. "Classpath Hell"에서 끝납니다.

4
sotms / # 요약은 어느 정도 답 것입니다. 프로젝트 목표가 프로젝트 Jigsaw에 맞춰져 있는지 확인할 수 있습니다 . 그 외에는 소비자에게 지원을 제공하는 도서관 / 서비스에 있어서도 최신의 문제라고 생각합니다.
Naman

4
@Taschi Java 9 이전의 모든 코드에 문제가 있었고 대부분의 경우 문제가 없었기 때문에 클래스 경로 지옥만으로는 모듈화가 정당화되지 않는다고 생각합니다 (개인적으로는 문제가 없었습니다).
Younes EO

1
@Naman이 프로젝트 퍼즐의 목표를 제시하는 것은 참으로 좋은 주장입니다.
Younes EO

8
@Younes El Ouarti, "Classpath Hell"을 제거하는 것은 Project Jigsaw의 두 가지 목표 중 하나입니다. 그것이 Jigsaw를 다루는 충분한 이유가 아니라고 생각한다면, 글쎄요 ... 나는 당신의 의견에 동의하며, 가능한 한 Jigsaw를 피합니다.

답변:


132

아니.

모듈로 전환 할 필요가 없습니다.

모듈로 전환 할 필요가 없었습니다.

Java 9 이상 릴리스는 이름이 지정되지 않은 모듈의 개념을 통해 기존 클래스 경로에서 기존 JAR 파일을 지원하며 우주의 열사 때까지 지원할 것입니다.

모듈 사용을 시작할지 여부는 전적으로 귀하에게 달려 있습니다.

많이 변경되지 않는 대규모 레거시 프로젝트를 유지한다면 노력할 가치가 없을 것입니다.

수년에 걸쳐 유지하기 어렵게 성장한 대규모 프로젝트에서 작업하는 경우 모듈화가 제공하는 명확성과 규율이 유익 할 수 있지만 많은 작업이 될 수 있으므로 시작하기 전에 신중하게 생각하십시오.

새 프로젝트를 시작하는 경우 가능하면 모듈로 시작하는 것이 좋습니다. 지금까지 많은 인기 라이브러리가 모듈업그레이드 되었으므로 필요한 모든 종속성이 이미 모듈 형식으로 제공 될 가능성이 높습니다.

라이브러리를 유지하는 경우 아직 수행하지 않았고 라이브러리의 모든 종속성이 변환 된 경우 모듈로 업그레이드하는 것이 좋습니다.

이 모든 것이 Java 8을 지나갈 때 몇 가지 걸림돌이 발생하지 않는다는 의미는 아닙니다.하지만 마주 치는 것은 모듈 자체 와는 아무 관련이 없습니다 . 우리는 우리가 2017 년 자바 (9) 출시 이후에 대해 들어 본 것이 가장 일반적인 마이그레이션 문제와 함께해야 할 버전 문자열의 구문에 대한 변경 과에 제거 또는 내부 API를 캡슐화 ( 예를 들어 , sun.misc.Base64Decoder)하는 대중을 위해 지원되는 대체가이 수년간 사용할 수있었습니다.


26

이 문제에 대한 내 조직의 의견 만 말할 수 있습니다. 우리 우리가 작업하는 모든 단일 프로젝트에 대해 모듈로 이동하는 과정에 있습니다. 우리가 구축하는 것은 기본적으로 마이크로 서비스 + 일부 클라이언트 라이브러리입니다. 마이크로 서비스의 경우 전환 modules은 우선 순위가 낮습니다. 코드는 이미 도커 컨테이너에 격리되어 있으므로 여기에 모듈을 "추가"하는 것은 (우리에게) 그다지 중요하지 않은 것 같습니다. 이 작업은 천천히 진행되고 있지만 우선 순위가 낮습니다.

반면에 클라이언트 라이브러리는 완전히 다른 이야기입니다. 나는 우리가 때때로 가지고있는 혼란을 말할 수 없습니다. 제가 전에 싫었던 점을 한 가지 설명하겠습니다 jigsaw. 모든 사람이 사용할 수 있도록 클라이언트에 인터페이스를 노출합니다. 자동으로 그 interface입니다 public- 세계에 노출. 일반적으로 내가하는 일은 package-private클라이언트에 노출되지 않는 일부 클래스가 해당 인터페이스를 사용하는 것입니다. 나는 클라이언트가 그것을 사용하는 것을 원하지 않습니다. 좋은가요? 잘못된.

첫 번째 문제는 이러한 package-private클래스가 커지고 더 많은 클래스를 원할 때 모든 것을 숨기는 유일한 방법 은 동일한 패키지에 클래스를 만드는 것입니다 .

  package abc:
        -- /* non-public */ Usage.java
        -- /* non-public */ HelperUsage.java
        -- /* non-public */ FactoryUsage.java
        ....

그것이 커지면 (우리의 경우에는 그렇습니다) 그 패키지는 너무 큽니다. 별도의 패키지로 이동한다고 말씀 하셨나요? 물론 이죠,하지만 그 HelperUsageFactoryUsage있을 것입니다 public그리고 우리는 처음부터 그것을 방지하기 위해 노력했다.

두 번째 문제 : 클라이언트의 모든 사용자 / 호출자 는 동일한 패키지 이름을 만들고 이러한 숨겨진 클래스를 확장 할 수 있습니다 . 우리에게 벌써 몇 번, 즐거운 시간이되었습니다.

modules: 아름다운 방법으로이 문제가 해결 public되지 않습니다 정말 public 더 이상; 지시문을 friend통해 액세스 할 수 있습니다 exports to. 이를 통해 코드 라이프 사이클 및 관리가 훨씬 쉬워집니다. 그리고 우리는 classpath 지옥에서 벗어납니다. 물론 maven/gradle우리를 위해 주로 처리하지만 문제 발생하면 고통이 매우 현실적입니다. 다른 많은 예도있을 수 있습니다.

즉, 전환은 (여전히) 쉽지 않습니다. 우선, 팀의 모든 구성원이 정렬되어야합니다. 두 번째 장애물이 있습니다. 내가 여전히 보는 가장 큰 두 가지는 : 구체적으로 무엇을 기준으로 각 모듈을 어떻게 분리합니까? 아직 확실한 답은 없습니다. 두 번째는 split-packages, 오 아름다운 "같은 클래스가 다른 모듈에 의해 내보내집니다"입니다. 라이브러리에서 이런 일이 발생하면 완화 할 수있는 방법이 있습니다. 하지만 이것이 외부 라이브러리라면 ... 그렇게 쉽지는 않습니다 .

jarAjarB(별도의 모듈) 에 의존 하지만 둘 다를 내 보내면 abc.def.Util놀랄 것입니다. 하지만이를 해결하는 방법이 있습니다. 어떻게 든 고통 스럽지만 해결할 수 있습니다.

전반적으로 모듈로 마이그레이션 한 이후 (여전히 수행하고 있음) 코드가 훨씬 더 깔끔해졌습니다. 그리고 귀사가 "코드 우선"기업이라면 이것은 중요합니다. 다른 한편으로, 나는 이것이 선임 건축가들에게 "너무 비싸고" "실제 이득이없는"것으로 여겨 졌던 회사들에 참여했습니다.


4
incites 감사합니다! 그래서 제가 얻은 것은 모듈화가 이전 버전에서 놓쳤던 액세스 제한이 많이 필요하다는 것입니다. 이것이 도서관에 얼마나 유용한 지 확실히 알 수 있습니다. REST / AMQP 등을 통해 서비스와 통신하는 경우. 이것은 다시 그다지 문제가 아니거나 오히려 이점이 없습니까? 모든 자바 9+ 코드가 모듈 식이어야한다고 임의로 말할 수 없을까요? 그래서 우리는 그것을 "도구"그 자체로 간주해야합니까? 그럼에도 불구하고 흥미 롭습니다.
Younes EO

유용한 것은 "접근 자"API 패턴입니다 (하지만 클래스로드 중 교착 상태를 피하기 위해 공용 정적 필드 대신 메서드가있는 개인 필드가 선호된다는 점에 유의하십시오). 여기를 참조하십시오 : wiki.netbeans.org/...
토마스 Myšík

경험을 공유해 주셔서 감사합니다! 고통 스럽지만 여전히 해결할 수있는 문제에 대한 자세한 내용이나 링크를 공유하면 좋을 것입니다.
botismarius

3
"문제 두 번째 : 클라이언트의 모든 사용자 / 호출자가 동일한 패키지 이름을 만들고 이러한 숨겨진 클래스를 확장 할 수 있습니다 ." Java 9 이전에는 이를 방지하기 위해 패키지를 봉인 할 수있었습니다 . (모듈이 훌륭한 아이디어라고 생각하고 모든 프로젝트에서 사용합니다.이 특정 사용 사례에는 모듈이 필요하지 않다는 점을 지적하고 싶었습니다.)
VGR
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.