Что касается OSGi модульности, то трудно себе представить большую модульность.
Каждый модуль представляет собой JAR файл у которого объявлены все "доступные" интерфейсы.
Все остальные классы скрыты и недоступны для других модулей.

Межмодульное взаимодействие происходит на основе единого реестра сервисов в JVM(ах).
Модуль может зависить от другого напрямую или косвенно, это означает, что в первом случае он не сможет функционировать, а во втором случае - его функциональность будет ограничена.
Чётко определён жизненный цикл модуля:
Загрузка - Запуск - Работа - Остановка - Выгрузка
Причём после остановки модуль может быть опять запущен. Каждый модуль может быть загружен/выгружен индивидуально вне связи с остальными модулями,
поэтому внутри модуля прямая ссылка на другие модули не доступна, а используется опосредованная ссылка через реестр сервисов.
Реестр сервисов на самом деле может быть распределённый. Благодаря тому, что Java классы сериализуются и могут быть переданы на другую JVM,
выполнение модулей на кластере происходит также как если бы это было на одной JVM.