Для аргументу припустимо, що 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.