Để tranh luận, hãy khẳng định rằng Java 8 (và trước đó) đã có một "dạng" mô-đun (lọ) và hệ thống mô-đun (classpath). Nhưng có những vấn đề nổi tiếng với những điều này.
Bằng cách xem xét các vấn đề, chúng tôi có thể minh họa động lực cho Jigsaw. (Điều sau giả định rằng chúng tôi không sử dụng Mô-đun OSGi, JBoss, v.v., những mô-đun này chắc chắn cung cấp giải pháp.)
Vấn đề 1: công khai quá công khai
Hãy xem xét các lớp sau (giả sử cả hai đều là công khai):
com.acme.foo.db.api.UserDao
com.acme.foo.db.impl.UserDaoImpl
Tại Foo.com, chúng tôi có thể quyết định rằng nhóm của chúng tôi nên sử dụng UserDao
và không sử dụng UserDaoImpl
trực tiếp. Tuy nhiên, không có cách nào để thực thi điều đó trên classpath.
Trong Jigsaw, một mô-đun có chứa một module-info.java
tệp cho phép chúng ta trình bày rõ ràng những gì là công khai đối với các mô-đun khác. Đó là, công có sắc thái. Ví dụ:
module com.acme.foo.db {
exports com.acme.foo.db.api;
}
Vấn đề 2: phản xạ là không thể kiềm chế
Với các lớp trong # 1, ai đó vẫn có thể làm điều này trong Java 8:
Class c = Class.forName("com.acme.foo.db.impl.UserDaoImpl");
Object obj = c.getConstructor().newInstance();
Điều đó có nghĩa là: phản xạ là mạnh mẽ và cần thiết, nhưng nếu không được kiểm soát, nó có thể được sử dụng để tiếp cận bên trong của một mô-đun theo những cách không mong muốn. Mark Reinhold có một ví dụ khá đáng báo động . (Bài SO ở đây .)
Trong Jigsaw, tính đóng gói mạnh cung cấp khả năng từ chối quyền truy cập vào một lớp, bao gồm cả phản xạ. (Điều này có thể phụ thuộc vào cài đặt dòng lệnh, đang chờ thông số kỹ thuật sửa đổi cho JDK 9.) Lưu ý rằng vì Jigsaw được sử dụng cho chính JDK, Oracle tuyên bố rằng điều này sẽ cho phép nhóm Java đổi mới nội bộ nền tảng nhanh hơn.
Vấn đề 3: classpath xóa các mối quan hệ kiến trúc
Một nhóm thường có một mô hình tinh thần về mối quan hệ giữa các lọ. Ví dụ, foo-app.jar
có thể sử dụng foo-services.jar
mà sử dụng foo-db.jar
. Chúng tôi có thể khẳng định rằng các lớp trong foo-app.jar
không nên bỏ qua "lớp dịch vụ" và sử dụng foo-db.jar
trực tiếp. Tuy nhiên, không có cách nào để thực thi điều đó thông qua classpath. Mark Reinhold đề cập đến điều này ở đây .
Để so sánh, Jigsaw cung cấp một mô hình trợ năng rõ ràng, đáng tin cậy cho các mô-đun.
Vấn đề 4: Thời gian chạy nguyên khối
Thời gian chạy Java là nguyên khối rt.jar
. Trên máy của tôi, nó là hơn 60 MB với 20k lớp! Trong thời đại của các dịch vụ vi mô, các thiết bị IoT, v.v., việc có Corba, Swing, XML và các thư viện khác trên đĩa là điều không mong muốn nếu chúng không được sử dụng.
Jigsaw tự chia nhỏ JDK thành nhiều mô-đun; ví dụ java.sql chứa các lớp SQL quen thuộc. Có một số lợi ích cho điều này, nhưng một cái mới là jlink
công cụ. Giả sử một ứng dụng được mô-đun hóa hoàn toàn, hãy jlink
tạo hình ảnh thời gian chạy có thể phân phối được cắt bớt để chỉ chứa các mô-đun được chỉ định (và các phần phụ thuộc của chúng). Nhìn về phía trước, Oracle hình dung ra một tương lai nơi các mô-đun JDK được biên dịch trước thời hạn thành mã gốc. Mặc dù jlink
là tùy chọn và việc biên dịch AOT là thử nghiệm, chúng là những dấu hiệu chính cho thấy vị trí của Oracle.
Vấn đề 5: Phiên bản
Rõ ràng là classpath không cho phép chúng ta sử dụng nhiều phiên bản của cùng một jar: ví dụ bar-lib-1.1.jar
và bar-lib-2.2.jar
.
Jigsaw không giải quyết vấn đề này; Mark Reinhold nêu lý do ở đây . Ý chính là Maven, Gradle và các công cụ khác đại diện cho một hệ sinh thái lớn để quản lý sự phụ thuộc và một giải pháp khác sẽ có hại nhiều hơn là có lợi.
Cần lưu ý rằng các giải pháp khác (ví dụ OSGi) thực sự giải quyết được vấn đề này (và các giải pháp khác, ngoài # 4).
Kết luận
Đó là một số điểm chính của Jigsaw, được thúc đẩy bởi các vấn đề cụ thể.
Lưu ý rằng việc giải thích tranh cãi giữa các Mô-đun Jigsaw, OSGi, JBoss, v.v. là một cuộc thảo luận riêng biệt thuộc về một trang Stack Exchange khác. Có nhiều sự khác biệt giữa các giải pháp hơn được mô tả ở đây. Hơn nữa, đã có đủ sự đồng thuận để phê duyệt Phiếu Xem xét lại Công khai cho JSR 376.