Вы находитесь на странице: 1из 16

Source code: https://github.com/mcculls/osgi-in-action (в файле common.

xml следует поставить


<property name="compile.level" value="1.8"/> вместо 1.5, чтобы ant собрал проект. После сборки
можно изучить pom.xml в META-INF, там используется maven-bundle-plugin)

https://docs.osgi.org/specification/osgi.core/7.0.0/index.html

Если вкратце, то OSGI – это модульный слой в Java. Позволяет логически разделить проект на
бандлы = .jar, в дополнение может устанавливать им модификаторы доступа: public, private и
protected (build.properties). Касательно жизненного слоя предоставляет возможность
динамически подгружать бандлы в собранный проект (администрирование). Сервисный слой –
все это реализует.

- стр.17 (chapter 01)

Для каждого бандла есть класс Activator, который наследуется от BundleActivator, там два метода:
stop() и start(). start() регистрирует сервисы в регистре сервисов, stop() убирает
зарегистрированные сервисы (по умолчанию он и так это делает). Фреймворк OSGI проверяет все
имплементации BundleActivator.

Так выглядит дерево простого OSGI проекта:


Файл service\org.foo.hello\build.xml:

Код сервиса provider:


Так выглядит пример класса main из source code, видим, что вызывается provider и
аналогичный consumer:
Результат запуска .jar файла в командной строке (исполняется код provider’а):

- стр. 31 (chapter 02)


Сборка модульного проекта

Визуальное отличие модульной и немодульной построения системы (там внизу еще есть папка
launcher, она оказывается тоже используется):

Main скрыт в папке launcher, как видим без main никуда:

Сам по себе launcher.jar универсальный, при его запуске указывается путь к пакету бандлов
В классе Main создается list бандлов, из пути указанному в передаваемых параметрах
(java -Djava.specification.version=1.8 -jar launcher.jar bundles):

Видим Framework из пакета org.osgi.framework, который вероятно и будет заниматься всей


магией.

Инициализация Framework и установка в BundleContext полученных .jar файлов (их конвертация) в


цикле, выявление Main-Class.
Информация о Main-Class берется из манифеста. OSGI располагает всю информацию о бандле в
файле manifest.mf. С приведенным до этого примером он предельно прост, где просто
указывается путь к классу main.

В этом примере рассмотрим класс shape. Интерфейс shape не имеет main:

Потому Main-Class в манифесте не указывается, но присутствует очень много иной информации:

Bundle-SymbolicName: org.foo.shape –> уникальный идентификатор, который следует правилу


reverse-domain-name scheme.
Bundle-Version: 2.0 –> позволяет не менять Bundle-SymbolicName, и добавляет номер версии,
сохраняя уникальность имени бандла.

Bundle-ManifestVersion: 2 –> так как OSGI не всегда имел своего рода определенные стандарты,
только 2-ая версия определяет использование Bundle-SymbolicName.

Import-Package: -> импорт классов, задекларированных в Export-Package:, тем самым скрывая


реализацию (it must find a matching export).

Бандл javax.swing OSGI заимствует из JRE.

В данном примере атрибутом Main-Class обладает бандл paint:


Собственно, вот он main:

Далее идет запуск бандлов и запуск main, если он имелся в списке:


build.xml выглядит следующим образом:

После сборки в каждом модуле появится папка build:


В дополнение в проекте появится папка bundles и launcher.jar:

Запуск launcher.jar работает только, если явно указывается версия java


(java -Djava.specification.version=1.8 -jar launcher.jar bundles):
У Ankey класс Main находится в аналогичном launcher.jar:
- стр 72 (chapter 03)

Жизненный цикл

В отличие от модульного слоя, который зависит от метаданных, жизненный цикл зависит от API.

Apache Felix, Eclipse Equinox, and Knopflerfish – все это реализации фрэймворка OSGI, своего рода
оболочка. Сама оболочка написана на джаве и взаимодействует с фреймворком OSGI в лаунчере
посредством интерефейса BundleActivator:

Собственно этот класс прописывается в метаданных как BundleActivator:


Работает все аналогично через универсальный лаунчер, запускаем shell, он будет бандлом под
номером 1:

Открывается сокет на порту 7070, который может принимать команды.

Через telnet (telnet localhost 7070) можно обратиться к шеллу и установить бандлы по порядку:
И так далее, все запускается и останавливается в режиме онлайн:

И также при желании отключается:


Следует понимать, что ключом OSGI является 3 интерфейса: BundleActivator, BundleContext, and
Bundle.

BundleActivator – устанавливает правило, что класс будет использовать методы .start() и .stop() –
аналог main (main уже есть в лаунчере, где поэтапно вызываются бандлы).

BundleContext (https://docs.osgi.org/javadoc/r4v43/core/org/osgi/framework/BundleContext.html) –
позволяет бандлу взаимодействовать с фреймворком, включает методы Register, Retrieve, Get,
Install и прочие. Создается для бандла, называется так благодаря используемому паттерну State
(Состояние – Контекст хранит ссылку на объект состояния и делегирует ему работу, зависящую от
внутреннего состояния, для большего понимания лучше ознакомиться с самим паттерном -
https://ru.wikipedia.org/wiki/Состояние_(шаблон_проектирования)) – команда install.

Bundle – этот интерфейс создается для каждого установленного бандла (который .jar), определяет
способы управления жизненным циклом установленного бандла (пример которого также можно
посмотреть в вышеописанном паттерне) – команды start, stop (the result of Bundle.start() depends
on the current state of the associated bundle. If the bundle INSTALLED, it transitions to ACTIVE via the
RESOLVED and STARTING states. If the bundle is UNINSTALLED, the method throws an
IllegalStateException). Если у бандла есть активатор, вызывается BundleActivator.start().

Фреймворк собственно грамотно инициализирует все эти взаимосвязи.

## После установки бандла фреймворк больше не нуждается в исходном .jar файле, так как
сохраняет копию в bundle cache.

Вам также может понравиться