еда полезней и вкусней.
410013796724260
• Webmoney
R335386147728
Z369087728698
Ресурсные бандлы OSGiСтруктура bundle с примером представлена на странице описания спецификации динамической модульной системы OSGi (Open Services Gateway Initiative). В спецификации OSGi модуль именуют как bundle. В этой статье будет рассмотрен пример создания bundle-ресурса, который будет использоваться другим бандлом. В качестве ресурса включим в бандл объект локализации интерфейса приложения Locale. В качестве общих ресурсов модулей системы могут быть использованы изображения Image, свойства Properties и т.д. Пример использования бандла-ресурсовПри разработке и тестировании примера с бандлом ресурсов будут созданы два maven-проекта :
Описание bundle-resourceBundle ресурсов создает и хранит объект Locale. Проект модуля ресурсов bundle-resource включает интерфейс IResource.java, реализацию ResourceImpl.java и активатор ResourceActivator.java. Листинг интерфейса IResource.javaimport java.util.Locale; public interface IResource { public Locale getLocale(); public void setLocale(final String lang); } Интерфейс включает методы чтения и записи (get/set) объекта локализации Locale. Листинг класса ResourceImpl.javaimport java.util.Locale; public class ResourceImpl implements IResource { private static Locale locale; public Locale getLocale() { return locale; } public void setLocale(final String lang) { locale = new Locale(lang); } } Класс ResourceImpl реализует методы интерфейса IResource и включает статический объект locale, который создается в методе setLocale. Данный метод позволяет определить язык локализации системы в режиме run-time. Листинг активатора бандла ресурсов ResourceActivator.javaimport org.osgi.framework.BundleContext; import org.osgi.framework.BundleActivator; public class ResourceActivator implements BundleActivator { private static int start_count = 0; private String[] locales = {"ru", "de", "en"}; public void start(BundleContext context) throws Exception { int idx = start_count % 3; start_count++; new ResourceImpl().setLocale(locales[idx]); System.out.println("start bundle-resource"); } public void stop(BundleContext context) throws Exception { System.out.println("stop bundle-resource"); } } Активатор бандла при старте (метод start) получает в качестве параметра контекст контейнера context типа BundleContext и определяет объект локализации интерфейса Locale. Язык локализации определяется согласно значению счетчика стартов бандла start_count, т.е. при каждом старте значение счетчика увеличивается и для Locale выбирается очередное значение массива locales. В методе stop освобождаются ресурсы bundle. Описание сборки pom.xmlДля сборки проекта bundle-resource используется pom.xml следующего содержания : <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.resources</groupId> <artifactId>bundle-resource</artifactId> <packaging>bundle</packaging> <version>1.0.0</version> <name>Module resources</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.apache.felix.framework</artifactId> <version>5.6.1</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.groupId}.resource </Bundle-SymbolicName> <Bundle-Name> ${project.name} </Bundle-Name> <Bundle-Version> ${project.version} </Bundle-Version> <Bundle-Activator> ${project.groupId}.ResourceActivator </Bundle-Activator> <Export-Package> com.osgi.resources </Export-Package> </instructions> </configuration> </plugin> </plugins> </build> </project> В файле описания сборки pom.xml определяется зависимость фреймворка osgi (секция <dependency>) и параметры bundle для формирования манифеста META-INF/MANIFEST.MF. В тег <Export-Package> записываем наименование пакета. В результате сборки в поддиректории проекта target будет создан bundle в виде файла bundle-resource-1.0.0.jar с манифестом следующего содержания : Manifest-Version: 1.0 Bnd-LastModified: 1493449322857 Build-Jdk: 1.8.0_121 Bundle-Activator: com.osgi.resources.ResourceActivator Bundle-ManifestVersion: 2 Bundle-Name: Module resources Bundle-SymbolicName: com.osgi.resources.resource Bundle-Version: 1.0.0 Created-By: Apache Maven Bundle Plugin Export-Package: com.osgi.resources;\ uses:="org.osgi.framework";version="1.0.0" Import-Package: org.osgi.framework;version="[1.8,2)" Tool: Bnd-1.50.0 Описание bundle-localeСтруктура плагина bundle-locale включает только активатор LocaleActivator.java. Листинг активатора LocaleActivator.javaimport java.util.Locale; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleActivator; import com.osgi.resources.IResource; import com.osgi.resources.ResourceImpl; public class LocaleActivator implements BundleActivator { public void start(BundleContext context) throws Exception { System.out.println("start bundle-locale"); IResource resources = new ResourceImpl(); Locale locale = resources.getLocale(); if (locale == null) System.out.println("locale = null"); else System.out.println("Locale : " + "language = " + locale.getLanguage() + ", name = " + locale.getDisplayName()); } public void stop(BundleContext context) throws Exception { System.out.println("stop bundle-locale"); } } Бандл bundle-locale при старте получает объект локализации locale и выводит информацию в консоль. Описание сборки pom.xml<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.bundle</groupId> <artifactId>bundle-exchange</artifactId> <packaging>bundle</packaging> <version>1.0.0</version> <name>Bundle locale</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.apache.felix.framework</artifactId> <version>5.6.1</version> </dependency> <dependency> <groupId>com.osgi.resources</groupId> <artifactId>bundle-resource</artifactId> <version>1.0.0</version> <scope>provided</scope> </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.groupId}.locale </Bundle-SymbolicName> <Bundle-Name> ${project.name} </Bundle-Name> <Bundle-Version> ${project.version} </Bundle-Version> <Bundle-Activator> ${project.groupId}.LocaleActivator </Bundle-Activator> <Import-Package> org.osgi.framework.*, com.osgi.resources </Import-Package> </instructions> </configuration> </plugin> </plugins> </build> </project> В файле описания сборки pom.xml определяется зависимость плагина от артефакта service-resource на время разработки (provided), необходимая для компиляции и создания bundle. Чтобы maven нашел данный артефакт в репозитории необходимо выполнить в предыдущем проекте bundle-resource команду mvn install, которая загрузит артефакт в локальный репозиторий. В секции Import-Package необходимо дополнительно определить используемые бандлом пакеты. В результате сборки в поддиректории проекта target будет создан bundle в виде файла bundle-locale-1.0.0.jar с манифестом следующего содержания : Manifest-Version: 1.0 Bnd-LastModified: 1493449570534 Build-Jdk: 1.8.0_121 Bundle-Activator: com.osgi.bundle.LocaleActivator Bundle-ManifestVersion: 2 Bundle-Name: Bundle locale Bundle-SymbolicName: com.osgi.bundle.locale Bundle-Version: 1.0.0 Created-By: Apache Maven Bundle Plugin Export-Package: com.osgi.bundle;uses:="org.osgi.framework,\ com.osgi.resources";version="1.0.0" Import-Package: com.osgi.resources;version="[1.0,2)",\ org.osgi.framework;version="[1.8,2)" Tool: Bnd-1.50.0 ТестированиеКак было отмечено выше, в архив примеров входит папка «osgi.container», в которой размещается org.eclipse.osgi_3.7.1.R37x_v20110808-1106.jar для создания контейнера Equinox. Для автоматической загрузки плагинов (бандлов) их необходимо разместить в поддиректории «osgi.container/bundles», а в поддиректории «osgi.container/configuration» настроить файл инициализации config.ini следующим образом : osgi.bundles=bundles/bundle-resource-1.0.0.jar@start, \ bundles/bundle-locale-1.0.0.jar@start После этого при создании контейнера Equinox бандлы будут загружаться и стартовать автоматически. А в консоли мы увидим следующую «картину» : java -jar org.eclipse.osgi_3.7.1.R37x_v20110808-1106.jar -console osgi> start bundle-resource start bundle-locale Locale : language = ru, name = Russian ss Framework is launched. id State Bundle 0 ACTIVE org.eclipse.osgi_3.7.1.R37x_v20110808-1106 1 ACTIVE com.osgi.resources.locale_1.0.0 2 ACTIVE com.osgi.bundle.locale_1.0.0 При инициализации бандлов bundle-resource создал Locale с кириллицей RU_ru, информацию о которой в консоль вывел bundle-locale. Поскольку при каждом перестарте создается новый объект локализации Locale (см. ResourceActivator), то проверим это поочередной остановкой и стартом каждого из бандлов. osgi> stop 1 stop bundle-resource osgi> start 1 start bundle-resource osgi> stop 2 stop bundle-locale osgi> start 2 start bundle-locale Locale : language = de, name = German osgi> stop 1 stop bundle-resource osgi> start 1 start bundle-resource osgi> stop 2 stop bundle-locale osgi> start 2 start bundle-locale Locale : language = en, name = English osgi> stop 1 stop bundle-resource osgi> start 1 start bundle-resource osgi> stop 2 stop bundle-locale osgi> start 2 start bundle-locale Locale : language = ru, name = Russian Можно сказать, что все «задуманное сработало». Конечно же, при смене языка локализации в системе должен работать механизм «публикации/подписки», но это уже отдельная тема, рассмотренная здесь. Пример использования сервисных бандлов показывает, как можно создать и зарегистрировать сервис в контейнере OSGi, а также взаимодействие бандлов посредством сервисов. Скачать исходный кодИсходные коды рассмотренного примера создания и тестирования ресурсного bundle для платформы OSGi в виде проектов Eclipse можно скачать здесь (1.25 Мб). Архив проекта дополнительно содержит директорию osgi.container, включающую org.eclipse.osgi_3.7.1.R37x_v20110808-1106.jar для создания контейнера Equinox и тестирования примера. |