Có cần chuyển sang mô-đun khi chuyển sang Java 9 + / Java 11 không?


80

Chúng tôi hiện đang di chuyển từ Java 8 sang Java 11. Tuy nhiên, việc nâng cấp các dịch vụ của chúng tôi ít khó khăn hơn chúng tôi dự đoán. Về cơ bản, chúng tôi chỉ phải thay đổi số phiên bản trong build.gradletệp của mình và các dịch vụ đã hoạt động vui vẻ. Chúng tôi đã nâng cấp các thư viện cũng như các dịch vụ (vi mô) sử dụng các thư viện đó. Không có vấn đề gì cho đến bây giờ.

cần thực sự chuyển sang mô-đun không? Điều này sẽ tạo ra chi phí không cần thiết IMHO. Bất kỳ gợi ý hoặc tài liệu đọc thêm được đánh giá cao.

Để làm rõ, có bất kỳ hậu quả nào nếu mã Java 9+ được sử dụng mà không giới thiệu các mô-đun không? Nó có thể trở nên không tương thích với mã khác không?


10
Đó là rủi ro tương tự mà bạn đã phải đối mặt trong Java 8: kết thúc trong "Địa ngục Classpath".

4
Bản tóm tắt sotms / # sẽ trả lời ở một mức độ nào đó. Bạn có thể kiểm tra xem mục tiêu dự án của bạn có phù hợp với Dự án ghép hình hay không . Ngoài ra, theo tôi, vấn đề cập nhật cũng quan trọng đối với các thư viện / dịch vụ cung cấp hỗ trợ cho người tiêu dùng.
Naman

4
@Taschi Tôi không nghĩ rằng địa ngục classpath chỉ biện minh cho việc sử dụng mô-đun, vì tất cả mã trước Java 9 đều gặp vấn đề đó và trong hầu hết các trường hợp, chúng tôi ổn với nó (cá nhân chưa bao giờ gặp vấn đề với nó).
Younes EO

1
@Naman đưa ra các mục tiêu của dự án ghép hình thực sự là một lập luận rất tốt.
Younes EO

8
@Younes El Ouarti, loại bỏ "Địa ngục Classpath" là một trong hai mục tiêu đã nêu của Project Jigsaw. Nếu bạn nghĩ rằng đó không phải là lý do chính đáng để xử lý Jigsaw, thì ... Tôi đồng ý với bạn, và tôi tránh Jigsaw bất cứ khi nào tôi có thể.

Câu trả lời:


132

Không.

Không cần phải chuyển sang mô-đun.

Chưa bao giờ có nhu cầu chuyển sang mô-đun.

Các bản phát hành Java 9 trở lên hỗ trợ các tệp JAR truyền thống trên đường dẫn lớp truyền thống, thông qua khái niệm về mô-đun không tên, và có thể sẽ làm như vậy cho đến khi vũ trụ chết vì nhiệt.

Có bắt đầu sử dụng mô-đun hay không là hoàn toàn tùy thuộc vào bạn.

Nếu bạn duy trì một dự án kế thừa lớn mà không thay đổi nhiều thì có lẽ nó không đáng để nỗ lực.

Nếu bạn làm việc trong một dự án lớn khó duy trì trong nhiều năm thì sự rõ ràng và kỷ luật mà mô-đun hóa mang lại có thể có lợi, nhưng nó cũng có thể là rất nhiều công việc, vì vậy hãy suy nghĩ kỹ trước khi bắt đầu.

Nếu bạn đang bắt đầu một dự án mới thì tôi thực sự khuyên bạn nên bắt đầu với các mô-đun nếu bạn có thể. Hiện tại, nhiều thư viện phổ biến đã được nâng cấp lên thành mô-đun , vì vậy có nhiều khả năng là tất cả các phần phụ thuộc mà bạn cần đều đã có sẵn ở dạng mô-đun.

Nếu bạn duy trì một thư viện thì tôi thực sự khuyên bạn nên nâng cấp nó thành một mô-đun nếu bạn chưa làm như vậy và nếu tất cả các phần phụ thuộc của thư viện của bạn đã được chuyển đổi.

Tất cả điều này không phải là để nói rằng bạn sẽ không gặp phải một vài trở ngại khi di chuyển qua Java 8. Những người bạn làm cuộc gặp gỡ sẽ, tuy nhiên, nhiều khả năng không có gì để làm với các module cho mỗi gia nhập . Những vấn đề di cư phổ biến nhất mà chúng tôi đã nghe nói về kể từ khi chúng tôi phát hành Java 9 năm 2017 phải làm gì với những thay đổi cú pháp của chuỗi phiên bản và cho loại bỏ hoặc đóng gói các API nội bộ ( ví dụ , sun.misc.Base64Decoder) mà công cộng, thay thế được hỗ trợ có đã có sẵn trong nhiều năm.


26

Tôi chỉ có thể cho bạn biết ý kiến ​​tổ chức của tôi về vấn đề này. Chúng tôi đang trong quá trình chuyển sang các mô-đun, cho mọi dự án đơn lẻ mà chúng tôi đang thực hiện. Những gì chúng tôi đang xây dựng về cơ bản là các dịch vụ vi mô + một số thư viện máy khách. Đối với các dịch vụ vi mô, việc chuyển đổi sang modulesbằng cách nào đó có mức độ ưu tiên thấp hơn: mã ở đó đã bị cô lập bằng cách nào đó trong bộ chứa docker, vì vậy việc "thêm" các mô-đun vào đó dường như (đối với chúng tôi) không quan trọng lắm. Công việc này đang được thực hiện chậm, nhưng mức độ ưu tiên thấp.

Mặt khác, thư viện khách hàng là một câu chuyện hoàn toàn khác. Tôi không thể cho bạn biết sự lộn xộn mà chúng tôi có đôi khi. Tôi sẽ giải thích một điểm mà tôi ghét trước đây jigsaw. Bạn hiển thị giao diện cho khách hàng, cho mọi người sử dụng. Tự động đó interfacepublic- tiếp xúc với thế giới. Thông thường, những gì tôi làm, sau đó có một số package-privatelớp, không được tiếp xúc với máy khách, sử dụng giao diện đó. Tôi không muốn khách hàng sử dụng nó, nó là nội bộ. Nghe hay không? Sai lầm.

Vấn đề đầu tiên là khi các package-privatelớp đó phát triển và bạn muốn có nhiều lớp hơn, cách duy nhất để ẩn mọi thứ là tạo các lớp trong cùng một gói:

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

Khi nó phát triển (trong trường hợp của chúng tôi là như vậy), những gói đó quá lớn. Bạn nói chuyển sang một gói riêng? Chắc chắn, nhưng sau đó HelperUsageFactoryUsagesẽ được publicvà chúng tôi cố gắng tránh điều đó ngay từ đầu.

Vấn đề thứ hai: bất kỳ người dùng / người gọi nào của khách hàng của chúng tôi có thể tạo cùng một tên gói và mở rộng các lớp ẩn đó. Nó đã xảy ra một vài lần với chúng tôi rồi, những lần vui vẻ.

modulesgiải quyết vấn đề này theo một cách hay: publickhông thực sự public nữa; Tôi có thể có friendquyền truy cập thông qua exports tochỉ thị. Điều này làm cho vòng đời và quản lý mã của chúng tôi dễ dàng hơn nhiều. Và chúng tôi thoát khỏi địa ngục classpath. Tất nhiên maven/gradlexử lý điều đó cho chúng tôi là chủ yếu, nhưng khi vấn đề, nỗi đau sẽ rất thực tế. Cũng có thể có nhiều ví dụ khác.

Điều đó nói rằng, quá trình chuyển đổi vẫn (vẫn) không dễ dàng. Trước hết, mọi người trong nhóm cần phải được liên kết; thứ hai có các rào cản. Hai điểm lớn nhất mà tôi vẫn thấy là: làm thế nào để bạn tách từng mô-đun, dựa trên cái gì, cụ thể là gì? Tôi chưa có câu trả lời chắc chắn. Thứ hai là split-packages, ồ đẹp "cùng một lớp được xuất bởi các mô-đun khác nhau". Nếu điều này xảy ra với các thư viện của bạn, có nhiều cách để giảm thiểu; nhưng nếu đây là những thư viện bên ngoài ... không dễ dàng.

Nếu bạn phụ thuộc vào jarAjarB(các mô-đun riêng biệt), nhưng cả hai đều xuất abc.def.Util, bạn sẽ ngạc nhiên. Tuy nhiên, có nhiều cách để giải quyết vấn đề này. Bằng cách nào đó đau đớn, nhưng có thể giải quyết.

Nhìn chung, kể từ khi chúng tôi chuyển sang mô-đun (và vẫn vậy), mã của chúng tôi đã trở nên sạch hơn nhiều . Và nếu công ty của bạn là công ty "tiên phong", điều này rất quan trọng. Mặt khác, tôi đã từng tham gia vào các công ty bị các kiến ​​trúc sư cấp cao coi là "quá đắt", "không có lợi".


4
Cảm ơn vì các kích động! Vì vậy, những gì tôi nhận được là, mô-đun hóa đi kèm với các hạn chế truy cập cần thiết mà chúng tôi đã thiếu trong các phiên bản trước. Tôi chắc chắn có thể thấy điều này hữu ích như thế nào đối với các thư viện. Trong trường hợp một dịch vụ được giao tiếp qua REST / AMQP / v.v. điều này một lần nữa không phải là quá nhiều vấn đề, hay đúng hơn, không có lợi ích? Có lẽ chúng ta không thể tùy tiện nói rằng tất cả mã java 9+ phải là mô-đun? Vì vậy, chúng ta nên coi nó như một "công cụ" chính nó? Tuy nhiên, thú vị.
Younes EO

Những gì bạn có thể thấy hữu ích là một mẫu API "trình truy cập" (nhưng xin lưu ý rằng thay vì một trường tĩnh công khai, một trường riêng tư với các phương thức được ưu tiên hơn, để tránh bế tắc trong quá trình tải lớp). Xem tại đây: wiki.netbeans.org/…
Tomáš Myšík

Cảm ơn vì đã chia sẻ kinh nghiệm của bạn! Sẽ rất tốt nếu bạn chia sẻ thêm thông tin chi tiết hoặc liên kết đến những vấn đề bạn đã đề cập gây đau đớn nhưng vẫn có thể giải quyết được.
botismarius

3
“Vấn đề thứ hai: bất kỳ người dùng / người gọi nào của khách hàng của chúng tôi đều có thể tạo cùng một tên gói và mở rộng các lớp ẩn đó”. Rất lâu trước Java 9, các gói có thể được niêm phong để ngăn chặn điều này. (Tôi xảy ra để suy nghĩ module là một ý tưởng tuyệt vời và tôi sử dụng chúng trong tất cả các dự án của tôi, tôi chỉ muốn chỉ ra rằng trường hợp sử dụng cụ này không yêu cầu họ..)
VRG
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.