410013796724260
• Webmoney
R335386147728
Z369087728698
OSGi описание, примерПри проектировании и разработке приложений возникает необходимость обеспечить модульность решения, которая позволяет из компонентов (модулей) создавать различные по функциональности приложения. Каждый из модулей должен реализовывать определенный функционал приложения и может быть использован при необходимости в других приложениях. При этом модули должны слабо зависеть друг от друга, т.е. не зависеть от деталей реализации других модулей, а взаимодействовать с ними посредством лишь простых интерфейсов. Модульная структура приложения должна обеспечивать возможность обновления отдельных компонентов, позволяя, таким образом, исправлять и улучшать программное обеспечение не всё целиком, а только отдельные его части. В качестве примера можно привести модуль учета валют. На начальном этапе разработки данный модуль может быть упрощен и использовать только одну валюту. С развитием проекта функционал модуля можно расширить для учета нескольких валют и курсовых разниц. Приложения должны обеспечивать продолжительную и непрерывную работу, в особенности это относится к серверным приложениям. Однако, нередки ситуации, когда приложение приходится останавливать для обновления или замены одного или нескольких модулей. Часто такое прерывание работы приложения является недопустимым. Компонентная платформа OSGi призвана решить вышеуказанные требования, а также и некоторые другие. OSGi (Open Services Gateway Initiative) представляет собой спецификацию динамической модульной системы и сервисной платформы для Java-приложений, разрабатываемую консорциумом OSGi Alliance. Данная спецификация определяет модель построения приложения из компонентов, которая динамически может связывать различные модули. Состав компонентов может изменяться во время выполнения приложения (run-time). Взаимодействие между компонентами осуществляется с помощью сервисов, которые зарегистрированы в регистре сервисов (Service Register). Таким образом, технология OSGi определяет сервис-ориентированную платформу построения приложений с поддержкой модульности. Платформа OSGi оперирует модулями, называемыми бандлами (bundle). Каждый bundle в OSGi – это логически завершённый программный компонент, реализующий определенный функционал. Платформа OSGi позволяет управлять модульным приложением, предоставляя ему следующие возможности :
Спецификация OSGi определяет наряду с вышеперечисленными также множество других стандартных сервисов, которые вместе составляют набор сервисов OSGi (OSGi Service Compendium). Благодаря открытости платформы OSGi, использование bundle, предоставляющих приложению всевозможные сервисы, является простой задачей. Реализации платформы OSGiСпецификация платформы OSGi описывает интерфейсы и поведение стандартных сервисов, предоставляемых платформой. OSGi разрабатывается с 1999-го года и имеет несколько реализациий :
Модули платформы OSGi, bundleВ терминологии OSGi модуль, называемый bundle, представляет собой обычный JAR-архив (Java ARchive). Здесь необходимо отметить, что при разработке java приложений, как правило, используются различные библиотеки, представляющие собой, также JAR-архивы. Использование подобных библиотек может быть сопряжено с определенными сложностями. В java-библиотеке разработчику, как правило, доступны все классы, поскольку разработчики библиотек не имеют возможности спрятать классы, используемые для реализации их внутренней логики. Таким образом, если используется код, который не предполагался для применения вне библиотеки, то можно столкнуться с несовместимостью при использовании новой версии библиотеки или нарушить ее корректное функционирование. Еще одной проблемой разработчиков является так называемый JAR Hell, о который многие програмисты сломали немало копий. Суть этой проблемы состоит в том, что как только в проекте начинают использоваться разные версии одной и той же библиотеки, то можно столкнуться с ситуацией, когда один и тот же класс имеет разные методы в разных версиях библиотеки. Java же устроена так, что будет использована первая версия библиотеки, которую найдет загрузчик классов. Тем самым, обратившись в коде к какому-либо классу во время выполнения программы, можно неожиданно получить ошибку, что метод, к которому Вы обращаетесь, не существует. Это связано с тем, что на этапе выполнения JVM ничего не знает о версии библиотеки, которая должна использоваться в том или ином случае. Отличие bundle от библиотеки JARСтоит отметить, что разработчики OSGi решили не изменять структуру JAR-файлов для обеспечения модульности, а просто включили в них дополнительную информацию (в файл META-INF/MANIFEST.MF), которая используется средой OSGi. Эта дополнительная информация никак не влияет на использование JAR-файлов в обычных Java-приложениях. Итак, чтобы JAR-файл стал OSGi-компонентом, в него добавляются данные, которые определяют, какие пакеты данного набора доступны для использования вне его (Export-Package) и какие пакеты других наборов требуются для работы этого набора (Import-Package). При этом возможно задать как версию API, которую набор предоставляет для других наборов, так и версию или диапазон версий API, которые набор требует для своей работы от них же. Все классы набора, которые не располагаются в его экспортируемой секции, не доступны вне набора (Private). Таким способом OSGi-компонент выполняет требование слабой связности. Так как зависимости между компонентами и интерфейсы, предоставляемые этими компонентами, имеют четкие версии, среда выполнения OSGi позволяет легко избегать ситуаций JAR Hell. Немного расширив описание обычного JAR-файла и добавив поддержку этого описания в среду выполнения, OSGi-сообщество решило проблему создания модулей в Java. Среда выполнения OSGi позволяет динамически загружать и выгружать компоненты во время выполнения. Более того, OSGi отслеживает зависимости между компонентами и динамически разрешает их. Компоненты OSGi bundle выполняют определенные функции и включают :
Согласно спецификации OSGi для bundle, реализующего интерфейс BundleActivator, определен следующий жизненный цикл (Lifecycle) :
Схема жизненного цикла bundle взята из спецификации OSGi. Дополнительные метаданные OSGi компонентаOSGi-компонент (bundle) должен включать дополнительные метаданные в файле META-INF/MANIFEST.MF. Некоторые из основных представлены ниже :
Взаимодействие OSGi бандловСогласно спецификации OSGi можно использовать несколько способов взаимодействия бандлов :
Пример создания OSGi bundleРассмотрим простой пример создания OSGi bundle в IDE Eclipse. Структура maven проекта osgi.hello представлена на следующем скриншоте. OSGi bundle, как было отмечено выше, должен реализовывать интерфейс BundleActivator. Кроме этого, bundle должен включать при необходимости методы start и stop, чтобы контейнер мог стартовать и остановить bundle. В качестве параметра контейнер передает этим методам BundleContext, который позволяет модулю взаимодействовать с контейнером. В следующем листинге (Activator.java) представлен исходный код bundle : package com.osgi.sample; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; public class Activator implements BundleActivator { public void start(BundleContext context) throws Exception { System.out.println("Start plugin activator"); } public void stop(BundleContext context) throws Exception { System.out.println("Stop plugin activator"); } } Для сборки bundle в файл конфигурации pom.xml включен плагин maven-bundle-plugin от разработчиков Apache Felix, который использует (знаменитую в OSGi кругах) утилиту Bnd. Этот плагин конфигурируем следующим образом : <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.osgi.sample</groupId> <artifactId>osgi.hello</artifactId> <packaging>bundle</packaging> <version>1.0.0</version> <name>OSGI Demo Bundle</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.osgi.core</artifactId> <version>1.4.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>2.3.7</version> <extensions>true</extensions> <configuration> <instructions> <Bundle-SymbolicName> ${project.artifactId} </Bundle-SymbolicName> <Bundle-Name> ${project.name} </Bundle-Name> <Bundle-Version> ${project.version} </Bundle-Version> <Bundle-Activator> ${project.groupId}.Activator </Bundle-Activator> <Private-Package> ${project.groupId} </Private-Package> </instructions> </configuration> </plugin> </plugins> </build> </project> Следует обратить внимание на то, что наименование записей в секции instructions совпадают с наименованиями специфических заголовков для метаданных OSGi-модуля в META-INF/MANIFEST.MF. Это они и есть, только не в своём натуральном виде, а в виде инструкций bnd. Данная утилита достаточно интеллектуальна и умеет вычислять зависимости по коду и подставлять их в секцию Import-Package, а также добавлять различные метаданные. На основе своей конфигурации и вычислений она генерирует MANIFEST.MF : Листинг манифеста MANIFEST.MFManifest-Version: 1.0 Bnd-LastModified: 1485887772941 Build-Jdk: 1.7.0_67 Built-By: Kernel Bundle-Activator: com.osgi.sample.Activator Bundle-ManifestVersion: 2 Bundle-Name: OSGI Demo Bundle Bundle-SymbolicName: osgi.hello Bundle-Version: 1.0.0 Created-By: Apache Maven Bundle Plugin Export-Package: com.osgi.sample;uses:="org.osgi.framework";version="1.0.0" Import-Package: org.osgi.framework;version="[1.5,2)" Tool: Bnd-1.50.0 OSGi контейнер Equinox от Eclipce FoundationКонтейнер Equinox позволяет из командной строки выполнять команды по инсталляции, старту и останову bundle, а также получить дополнительную информацию. Чтобы открыть консоль OSGi при установленном на компьютере IDE Eclipse необходимо в командой строке войти в директорию <ECLIPSE_HOME>/plugins и выполнить следующую команду : java -jar org.eclipse.osgi_3.7.1.R37x_v20110808-1106.jar -console Примечание : в команде используется версия 3.7.1.R37x_v20110808-1106, включенная в IDE Eclipse Indigo. У Вас может быть другая версия. Если у Вас нет Eclipse, то можно воспользоваться прилагаемым в конце страницы архивом с исходным кодом рассмотренного примера, включающий директорию osgi.container, где все настроено для тестирования примера. Команды управления жизненым циклом bundle
Команды получения дополнительной информации
Получение дополнительной информации о пакетах фреймворка и зарегистрированных сервисах рассмотрено в описании примера взаимодействия бандла с сервисом. Чтобы увидеть всю справочную информацию org.eclipse.osgi_ХХХ.jar используйте команду «help». После выполнения представленной выше команды на экране появится приглашение osgi > . Теперь можно вводить команды для управления контейнером. Для просмотра инициализированных в контейнер модулей необходимо выполнить команду ss. osgi> ss Framework is launched. id State Bundle 0 ACTIVE org.eclipse.osgi_3.7.1.R37x_v20110808-1106 Теперь можно наш bundle инсталлировать в контейнер и стартовать : osgi> install file:F:/osgi.container/bundles/osgi.hello-1.0.0.jar Bundle id is 19 osgi> ss Framework is launched. id State Bundle 0 ACTIVE org.eclipse.osgi_3.7.1.R37x_v20110808-1106 19 INSTALLED osgi.hello_1.0.0 osgi> start 19 Start plugin activator osgi> ss Framework is launched. id State Bundle 0 ACTIVE org.eclipse.osgi_3.7.1.R37x_v20110808-1106 19 ACTIVE osgi.hello_1.0.0 Скачать исходный кодИсходные коды рассмотренного примера создания bundle для платформы OSGi в виде проекта Eclipse можно скачать здесь (1.23 Мб). Архив проекта дополнительно содержит директорию osgi.container, включающую org.eclipse.osgi_3.7.1.R37x_v20110808-1106.jar для создания контейнера Equinox и тестирования бандла. Пример создания bundle-сервиса, регистрация его в контейнере OSGi и взаимодействие bundle-сервиса с bundle-клиентом представлен на странице здесь. Описание механизма публикации/подписки с использованием фреймворка Felix представлен на странице Механизм publish/subscribe в OSGi. |