Java 9: ​​объединение пользовательского модульного образа времени выполнения со сторонней системой плагинов

Основываясь на сообщении в Твиттере, я собираюсь предположить, что Jigsaw станет частью Java. 9.

Читая о Jigsaw, я задал себе вопрос: что происходит, когда я выпускаю свое приложение с пользовательским модульным образом времени выполнения, но сторонний модуль требует дополнительных модулей JRE, которые не были выпущены вместе с приложением, потому что они не требовались приложение?

Представьте себе приложение, которое хочет извлечь выгоду из модульности. Он предоставляет сервисный интерфейс, который может быть реализован сторонним модулем. Приложение загружает все сторонние модули, обеспечивающие реализацию интерфейса службы, при запуске приложения. На мой взгляд, это отличный и простой способ предоставить общедоступный API для сторонних плагинов, и я могу себе представить, что использую его сам довольно часто.

Теперь есть также инструмент под названием jlink, который позволяет создавать выпуск приложения, который содержит не только модули приложения, но и требуемые модули JRE. Это называется настраиваемым модульным образом времени выполнения. Самое замечательное то, что релиз содержит только те модули JRE, которые фактически используются приложением, что предотвращает очень большой размер релиза. В настоящее время jlink сам выяснит, какие модули нужно включить. Однако модули, обеспечивающие реализацию службы, должны быть явно включены разработчиком, см. здесь. Я думаю, что это также отлично подходит для многих приложений, где разработчик не хочет требовать от пользователя установки JRE.

Проблема возникает, когда мы пытаемся использовать оба в одном приложении: пользовательский модульный образ времени выполнения содержит только те модули JRE, которые используются приложением. Однако подключаемый модуль может использовать модули JRE, которые не использовались приложением, и поэтому эти модули недоступны во время выполнения. Таким образом, плагин не будет работать.


Вот единственное решение, которое я могу придумать, однако оно далеко от совершенства:

Включите отсутствующие модули JRE в сторонний плагин. Хотя на первый взгляд это может показаться простым решением, на самом деле оно сопряжено с некоторыми проблемами.

Во-первых, это требует, чтобы разработчик подключаемого модуля знал, какие модули JRE включены в приложение. Если это неизвестно, они могут включать модуль JRE, который уже доступен в самом приложении, что может вызвать проблемы. Таким образом, становится частью общедоступного API, какие модули используются приложением. Я думаю, что это нежелательно, потому что это деталь реализации. Кроме того, он может меняться довольно часто.

Во-вторых, поскольку доступные модули JRE являются частью общедоступного API, их нужно как-то указать. Хотя это может работать через документацию, я думаю, что это должно быть указано в формальном коде. Например, можно было бы использовать предложение requires public в модуле приложения для всех модулей JRE, которые должны быть доступны для модуля подключаемого модуля. Это делает эти модули JRE доступными для подключаемого модуля, поскольку подключаемый модуль будет require модулем приложения.

В-третьих, возникает вопрос, желательно ли разрешать плагину использовать дополнительные модули JRE. Если это не так, вероятно, должно быть предложение для module-info.java, чтобы указать, что текущий модуль является плагином для данного другого модуля. Например, вместо использования require для модуля приложения можно было бы использовать для этого plugs in to или другое обозначение. Это не позволит модулю требовать какие-либо модули JRE. Однако это, вероятно, не сработает, поскольку другим сторонним модулям, которые требуются для подключаемого модуля, могут потребоваться дополнительные модули JRE. Таким образом, я думаю, что трудно предложить поддержку такого механизма.

В-четвертых, также сложно разрешить плагинам использовать дополнительные модули JRE. Это потребует либо совместимости разных модулей JRE в разных версиях, либо разработчика подключаемого модуля всегда будет включать дополнительные модули JRE в версию, которая совместима с версией модулей JRE в приложении. Я не уверен в том, что модули JRE должны быть совместимы в разных версиях, но я предполагаю, что это не так, потому что это предотвратит многие изменения в будущем.

Некоторые из моих предположений ошибочны? Может быть, просто включить модуль JRE в приложение и плагин? Может быть, дополнительные модули JRE в плагине также не обязательно должны быть совместимы с модулями JRE в приложении? В конце концов, они могут не взаимодействовать друг с другом.


Как нам решить эту архитектурную проблему? Существуют ли другие языки с модульной и частично выпускаемой средой выполнения? Как они решили проблему?

Обратите внимание, что аналогичные проблемы могут возникнуть с часто используемыми библиотеками, такими как Google guava или Apache commons. Однако этот вопрос в основном должен касаться проблем, возникающих при использовании пользовательского модульного образа времени выполнения.


person Stefan Dollase    schedule 03.04.2016    source источник


Ответы (1)


У меня была точно такая же идея, и я думал об этом уже несколько дней. Кажется, нет никаких хороших ресурсов для решения этой проблемы. Идея, которая у меня была, была бы пользовательской структурой. Платформа может позволить сторонним модулям запрашивать дополнительные модули зависимостей с помощью файла конфигурации. Затем фреймворк решит (это можно сделать через взаимодействие с пользователем), будут ли модули установлены в приложении. Модули JRE можно устанавливать непосредственно в папку модулей JRE, другие модули можно копировать в пользовательскую папку для упрощения обслуживания. Но для этого решения потребуется какая-то конечная точка от Oracle, которая позволит разработчикам загружать отдельные файлы jmod.

person groggy    schedule 12.02.2017