Для аргументу припустимо, що Java 8 (і раніше) вже має "форму" модулів (банки) та модульну систему (шлях до класу). Але з цим є добре відомі проблеми.
Вивчаючи проблеми, ми можемо проілюструвати мотивацію Jigsaw. (Далі передбачається, що ми не використовуємо OSGi, модулі JBoss тощо, що, безсумнівно, пропонує рішення.)
Проблема 1: громадськість теж публічна
Розглянемо наступні класи (припустимо, що обидва є загальнодоступними):
com.acme.foo.db.api.UserDao
com.acme.foo.db.impl.UserDaoImpl
На Foo.com ми можемо вирішити, що наша команда повинна використовувати, UserDao
а не використовуватиUserDaoImpl
безпосередньо. Однак немає можливості застосувати це на шляху до класу.
У Jigsaw модуль містить module-info.java
файл, який дозволяє нам чітко вказати, що є загальнодоступним для інших модулів. Тобто, публіка має нюанси. Наприклад:
module com.acme.foo.db {
exports com.acme.foo.db.api;
}
Проблема 2: рефлексія нестримна
З огляду на класи в №1, хтось все ще міг зробити це в Java 8:
Class c = Class.forName("com.acme.foo.db.impl.UserDaoImpl");
Object obj = c.getConstructor().newInstance();
Тобто: відображення є потужним і важливим, але якщо його не встановити, він може бути використаний, щоб потрапити до внутрішніх елементів модуля небажаними способами. Марк Рейнгольд має досить тривожний приклад . (Повідомлення SO тут .)
У Jigsaw, сильна інкапсуляція пропонує можливість заборонити доступ до класу, включаючи роздуми. (Це може залежати від налаштувань командного рядка, до перегляду технічних специфікацій для JDK 9.) Зверніть увагу: оскільки Jigsaw використовується для самого JDK, Oracle стверджує, що це дозволить команді Java швидше впровадити внутрішні компоненти платформи.
Проблема 3: шлях до класу стирає архітектурні взаємозв'язки
Команда, як правило, має ментальну модель відносин між банками. Наприклад, foo-app.jar
може використовувати foo-services.jar
який використовує foo-db.jar
. Ми можемо стверджувати, що класи в foo-app.jar
не повинні обходити "рівень обслуговування" і використовувати foo-db.jar
безпосередньо. Однак немає можливості застосувати це через шлях до класу. Марк Рейнгольд згадує про це тут .
Для порівняння, Jigsaw пропонує чітку, надійну модель доступності для модулів.
Завдання 4: монолітний час роботи
Час роботи Java є монолітним rt.jar
. На моїй машині це 60+ МБ з класами 20k! У епоху мікросервісів, пристроїв IoT тощо небажано мати на диску бібліотеки Corba, Swing, XML та інші, якщо вони не використовуються.
Jigsaw розбиває сам JDK на безліч модулів; Наприклад, java.sql містить знайомі класи SQL. У цього є кілька переваг, але інструментом є нова jlink
. Припускаючи, що програма повністю модулюється, jlink
генерується розподільне зображення під час виконання, яке обрізано, щоб містити лише вказані модулі (та їх залежності). Забігаючи вперед, Oracle передбачає майбутнє, коли модулі JDK компілюються заздалегідь у власний код. Незважаючи на те jlink
, що компіляція AOT є експериментальною, вони є основними ознаками того, куди рухається Oracle.
Проблема 5: встановлення версій
Загальновідомо, що шлях до класу не дозволяє нам використовувати кілька версій однієї і тієї ж jar: наприклад bar-lib-1.1.jar
і bar-lib-2.2.jar
.
Jigsaw не вирішує цю проблему; Обгрунтування тут викладає Марк Рейнгольд . Суть полягає в тому, що Maven, Gradle та інші інструменти представляють велику екосистему для управління залежністю, а інше рішення буде більше шкідливим, ніж корисним.
Слід зазначити, що інші рішення (наприклад, OSGi) справді вирішують цю проблему (та інші, крім №4).
Нижня лінія
Це деякі ключові моменти для Jigsaw, мотивовані конкретними проблемами.
Зверніть увагу, що пояснення суперечки між Jigsaw, OSGi, JBoss Modules тощо - це окрема дискусія, яка належить до іншого веб-сайту Stack Exchange. Існує набагато більше відмінностей між рішеннями, ніж описано тут. Більше того, було достатньо консенсусу для затвердження виборчого бюлетеня з перегляду громадських прав за JSR 376.