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.java
import java.util.Locale;
public interface IResource
{
public Locale getLocale();
public void setLocale(final String lang);
}
Интерфейс включает методы чтения и записи (get/set) объекта локализации Locale. Листинг класса ResourceImpl.java
import 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.java
import 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.java
import 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 и тестирования примера. |
