На прошлой неделе я посетил тренинг Ньютона, представленный Дэвидом Сэвиджем и Майком Фрэнсисом из Паремуса . Newton — это проект с открытым исходным кодом, нацеленный на реализацию спецификации SCA с использованием возможностей OSGi внутри одной JVM и JINI за ее пределами.
Цель
Создайте 2 составных приложения:
- Композитный 1: Публикация сервиса вне текущей JVM с использованием SCA с Spring DM и Newton
- Композит 2: Потребление услуг.
инструменты
Для этого я использовал:
- Maven 2 инструмент для сборки.
- Netbeans 6.5 IDE.
- Пружина ДМ 1.2.0 М2
- Ньютон 1.3.2
- Плагин Maven Felix для генерации пакетов.
Создание проекта
- Создайте новый групповой проект в Netbeans с именем sca .
- Новые проекты Maven:
- родительский проект, который будет содержать 3 подпроекта:
- API : интерфейс службы.
- импл : реализация сервиса.
- клиент : потребляющий услугу.
- Добавьте api-зависимость для impl и client .
- Добавьте каталоги ресурсов для проектов impl и client с пустыми XML-файлами Spring DM и Newton.
- Каталог проекта будет:
,
| — API
| | — pom.xml
| `- src
| `- главная
| `- Ява
| `- ком
| `- Jtunisie
| `- osgi
| `- sca
| `- IService.java
| — клиент
| | — pom.xml
| `- src
| `- главная
| | — Ява
| | `- ком
| | `- Jtunisie
| | `- osgi
| | `- sca
| | `- клиент
| | `- Activator.java
| `- ресурсы
| `- МЕТА-ИНФ
| | — ньютон
| | `- client.composite
| `- весна
| | — bundle-context-osgi.xml
| `- bundle-context.xml
| — impl
| | — pom.xml
| `- src
| `- главная
| | — Ява
| | `- ком
| | `- Jtunisie
| | `- osgi
| | `- sca
| | `- impl
| | `- Service.java
| `- ресурсы
| `- МЕТА-ИНФ
| | — ньютон
| | `- service.composite
| `- весна
| | — bundle-context-osgi.xml
| `- bundle-context.xml`
— pom.xml
IService содержит одну сигнатуру метода:
public interface IService extends Serializable {
String getMessage(String name);
}
Реализация Сервиса — это:
public class Service implements IService {
@Override
public String getMessage(String name) {
return "Hello " + name;
}
}
Активатор клиента (не Активатор OSGi):
public class Activator {
IService service;
public void setService(IService service) {
this.service = service;
}
public void init() {
String message = service.getMessage("world!!!!");
System.out.println(message);
}
}
Файлы Пом
- Измените три проекта для упаковки пакетов: добавьте <package> bundle </ packaging> в заголовки pom.
- Api будет экспортировать пакет com.jtunisie.osgi.sca
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package>com.jtunisie.osgi.sca</Export-Package>
<Bundle-SymbolicName>${pom.name}-${pom.version}</Bundle-SymbolicName>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
- impl также экспортирует пакет com.jtunisie.osgi.sca и сделает реализацию частной
<build>
<plugins>
<plugin>
<groupid>org.apache.felix</groupid>
<artifactid>maven-bundle-plugin</artifactid>
<extensions>true</extensions>
<configuration>
<instructions>
<export-package>com.jtunisie.osgi.sca</export-package>
<private-package>com.jtunisie.osgi.sca.impl</private-package>
<bundle-symbolicname>${pom.name}-${pom.version}</bundle-symbolicname>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
Примечание. Пакет
impl содержит интерфейс API, поэтому не развертывайте
пакет API . Да, нам не нужно включать
API в
пакет Impl . Просто импортируйте
пакет com.jtunisie.osgi.sca и разверните два пакета.
- Клиент пакет не экспортирует любой пакет:
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Private-Package>com.jtunisie.osgi.sca.client</Private-Package>
<Bundle-SymbolicName>${pom.name}-${pom.version}</Bundle-SymbolicName>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
- Добавьте заголовки Newton: Installable-Component-Templates — это имя составного файла в ресурсах | — META-INF | — каталог newton.
- Импл пом:
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package>com.jtunisie.osgi.sca</Export-Package>
<Private-Package>com.jtunisie.osgi.sca.impl</Private-Package>
<Bundle-SymbolicName>${pom.name}-${pom.version}</Bundle-SymbolicName>
<Installable-Component>true</Installable-Component>
<Installable-Component-Templates>META-INF/newton/service.composite</Installable-Component-Templates>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
-
- клиент пом:
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Private-Package>com.jtunisie.osgi.sca.client</Private-Package>
<Bundle-SymbolicName>${pom.name}-${pom.version}</Bundle-SymbolicName>
<Installable-Component>true</Installable-Component>
<Installable-Component-Templates>META-INF/newton/client.composite</Installable-Component-Templates>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
- клиент пом:
Издательский сервис
- Вернемся к пакету impl и его файлам Spring XML. Объявите простой bean-компонент Spring в bundle-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
>
<bean id="service" class="com.jtunisie.osgi.sca.impl.Service"/>
</beans>
- Опубликуйте его в bundle-context-osgi.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">
<osgi:service id="_service" interface="com.jtunisie.osgi.sca.IService" ref="service"/>
</beans>
Сервис теперь публикуется внутри локального контейнера OSGi с использованием Spring DM.
- Теперь мы выставим его за пределы локального контейнера. Чтобы сделать это, мы сначала добавляем свойство в наш открытый сервис, чтобы Newton мог его обнаружить. будет содержать bundle-context-osgi.xml .
<osgi:service id="_service" interface="com.jtunisie.osgi.sca.IService" ref="service">
<osgi:service-properties>
<entry key="newton.sca.service" value="sca_service"/>
</osgi:service-properties>
</osgi:service>
- Служба экспорта:
Ньютон в основном предоставляет сервисы, использующие RMI за пределами локальной JVM, и мы можем использовать OSGi внутри него. Составной файл представляет собой документ XML. Для редактирования давайте добавим этот тип в IDE Netbeans.
- Перейти к инструментам -> Параметры -> Разное
- В расширении файла нажмите «Создать» и добавьте в него композитный код «APPLICATION / xhtml + xml».
- Откройте service.composite.
- Редактировать service.composite, добавить две услуги для RMI и OSGi :
<service name="sca_service_rmi" >
<interface.java interface="com.jtunisie.osgi.sca.IService"></interface.java>
<binding.rmi/>
</service>
<service name="sca_service_osgi" >
<interface.java interface="com.jtunisie.osgi.sca.IService"></interface.java>
<binding.osgi/>
</service>
-
Мы можем использовать короткое объявление (но я его не проверял):
<service name="sca_service_rmi" >
<interface.java interface="com.jtunisie.osgi.sca.IService"></interface.java>
<binding.rmi/>
<binding.osgi/>
</service>
- Добавьте наш пакет как компонент, который реализован с помощью Spring:
<component name="srv">
<description>spring configuration</description>
<service name="sca_service" />
<sdm:implementation.spring />
</component>
Имя службы — это файл источника значения свойства newton.sca.service.
- У нас есть две службы привязки и один компонент. Теперь добавьте электромонтажные услуги:
<wire>
<source.uri>sca_service_rmi</source.uri>
<target.uri>srv/sca_service</target.uri>
</wire>
<wire>
<source.uri>sca_service_osgi</source.uri>
<target.uri>srv/sca_service</target.uri>
</wire>
- Добавить Impl композитный:
<?xml version="1.0" encoding="UTF-8"?>
<composite name="configuration"
xmlns:sdm="http://newton.cauldron.org/springdm">.
<service name="sca_service_rmi" >
<interface.java interface="com.jtunisie.osgi.sca.IService"></interface.java>
<binding.rmi/>
</service>
<service name="sca_service_osgi" >
<interface.java interface="com.jtunisie.osgi.sca.IService"></interface.java>
<binding.osgi/>
</service>
<component name="srv">
<description>spring configuration</description>
<service name="sca_service" />
<sdm:implementation.spring />
</component>
<wire>
<source.uri>sca_service_rmi</source.uri>
<target.uri>srv/sca_service</target.uri>
</wire>
<wire>
<source.uri>sca_service_osgi</source.uri>
<target.uri>srv/sca_service</target.uri>
</wire>
</composite>
- Мы закончили наш первый композит. Он публикует сервис внутри и вне JVM, настраивая только три XML-файла.
Использование сервиса:
Давайте использовать аннотации Spring, чтобы использовать этот сервис в
клиентском проекте.
- Добавьте spring-osgi-annotation к зависимости pom XML:
<dependency>
<groupId>org.springframework.osgi</groupId>
<artifactId>spring-osgi-annotation</artifactId>
<version>1.1.1</version>
</dependency>
Зарегистрируйте bean-компонент Activator в bundle-context.xml и включите процессор аннотаций
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-init-method="init">
<bean id="activator" class="com.jtunisie.osgi.sca.client.Activator"/>
<!-- annotation processor -->
<bean class="org.springframework.osgi.extensions.annotation.ServiceReferenceInjectionBeanPostProcessor"/>
</beans>
Метод init () будет вызываться как метод init-default.
- Нет необходимости в bundle-context-osgi.xml, мы можем его удалить.
- В классе Activator мы добавляем аннотацию Spring следующим образом:
@ServiceReference(filter="(newton.sca.reference=service_cons)")
public void setService(IService service) {
this.service = service;
}
Примечание. Фильтр используется для включения Ньютона.
- В составном файле мы добавляем сервисную ссылку с именем service_ref_rmi
<reference name="service_ref_rmi" multiplicity="0..1">
<interface.java interface="com.jtunisie.osgi.sca.IService" />
<binding.rmi/>
</reference>
- Объявите компонент с именем serv-test с именем ссылки в качестве значения фильтра newton.sca.reference
<component name="serv-test">
<description>spring configuration</description>
<reference name="service_cons" />
<sdm:implementation.spring />
</component>
- Ссылка на провод к компоненту:
<wire>
<source.uri>serv-test/service_cons</source.uri>
<target.uri>service_ref_rmi</target.uri>
</wire>
- Мы закончили наш второй композит:
<?xml version="1.0" encoding="UTF-8"?>
<composite name="service_test"
xmlns:sdm="http://newton.cauldron.org/springdm">
<reference name="service_ref_rmi" multiplicity="0..1">
<interface.java interface="com.jtunisie.osgi.sca.IService" />
<binding.rmi/>
</reference>
<component name="serv_test">
<description>spring configuration</description>
<reference name="service_cons" />
<sdm:implementation.spring />
</component>
<wire>
<source.uri>serv_test/service_cons</source.uri>
<target.uri>service_ref_rmi</target.uri>
</wire>
</composite>
Запуск компоновки SCA:
Прежде чем начать этот последний шаг, нам нужно добавить в папки и два файла.
- Ls
bin и т. д. привет LICENSE.txt publish-springdm-1.2.0.xml примеры
документов dk springdm
hello-config.script lib NOTICE.txt README.html var
- Каталог Springdm содержит пакеты Spring 1.2 и пакеты hello :
springdm
| — aopalliance.osgi-1.0-SNAPSHOT.jar
| — jcl104-over-slf4j-1.4.3.jar
| — log4j.osgi-1.2.15-SNAPSHOT.jar
| — slf4j-api-1.4. 3.jar
| — slf4j-api-1.5.2.jar
| — slf4j-log4j12-1.4.3.jar
| — slf4j-log4j12-1.5.2.jar
| — spring-2.5.5.jar
| — spring-aop-2.5.5.jar
| — spring-beans-2.5.5.jar
| — spring-context-2.5.5.jar
| — spring-context-support-2.5.5.jar
| — spring-core-2.5.5.jar
| — spring-osgi-annotation-1.2.0-m1-SNAPSHOT.jar
| — spring-osgi-core-1.2.0-m1.jar
| — spring- osgi-extender-1.2.0-m1.jar
`- spring-osgi-io-1.2.0-m1.jar
привет
| — client-1.0-SNAPSHOT.jar
`- impl-1.0-SNAPSHOT.jar
- publish-springdm-1.2.0.xml будет использоваться для публикации пакетов Spring
<?xml version="1.0" encoding="iso-8859-1"?>
<publish>
<item name="spring-2.5.5.jar" path="springdm/spring-2.5.5.jar" />
<item name="spring-aop-2.5.5.jar" path="springdm/spring-aop-2.5.5.jar" />
<item name="spring-beans-2.5.5.jar" path="springdm/spring-beans-2.5.5.jar" />
<item name="spring-context-2.5.5.jar" path="springdm/spring-context-2.5.5.jar" />
<item name="spring-context-support-2.5.5.jar" path="springdm/spring-context-support-2.5.5.jar" />
<item name="spring-core-2.5.5.jar" path="springdm/spring-core-2.5.5.jar" />
<item name="spring-osgi-annotation-1.2.0-m1-SNAPSHOT.jar" path="springdm/spring-osgi-annotation-1.2.0-m1-SNAPSHOT.jar" />
<item name="spring-osgi-core-1.2.0-m1.jar" path="springdm/spring-osgi-core-1.2.0-m1.jar" />
<item name="spring-osgi-extender-1.2.0-m1.jar" path="springdm/spring-osgi-extender-1.2.0-m1.jar" />
<item name="spring-osgi-io-1.2.0-m1.jar" path="springdm/spring-osgi-io-1.2.0-m1.jar" />
<item name="aopalliance.osgi-1.0-SNAPSHOT.jar" path="springdm/aopalliance.osgi-1.0-SNAPSHOT.jar" />
<item name="jcl104-over-slf4j-1.4.3.jar" path="springdm/jcl104-over-slf4j-1.4.3.jar" />
<item name="slf4j-api-1.4.3.jar" path="springdm/slf4j-api-1.4.3.jar" />
<item name="slf4j-log4j12-1.4.3.jar" path="springdm/slf4j-log4j12-1.4.3.jar" />
</publish>
- hello-config.script содержит подпрограммы сценария:
Exec и т.д. / скрипты / одной JVM-распред-инфра # установить JINI браузер ( опционально ) установщик установки и т.д. / примеры / jinibrowser.composite установщик установки и т.д. / экземпляры сервера cds.composite / # загружать пакеты в |
- Откройте два терминала и в первом мы выполним:
bin / container -fabricName = тест
на втором
bin / контейнер -fabricName = экземпляр теста = 1
Если используются 2 машины
bin / container -fabricName = test -bindAddress = machineIP (1) -serviceLookupURLs = jini: machineIP (1)
bin / container -fabricName = test -bindAddress = machineIP (2) -serviceLookupURLs = jini: machineIP (1) -instance = 1
- Выполните hello-config.script, введите его на двух терминалах.
> exec hello-config.script
- На первом jvm мы установим реализацию сервиса:
> установщик установить составной: sca_service
Служба теперь установлена, и вы можете проверить это в браузере jini.
- На другом jvm мы установим клиент. Давайте проверим это наличие:
> cds find ser *
> Content [service_test: {bundle.symbolic.name = client-1.0-SNAPSHOT, type = component.template, версия = 1.0.0.SNAPSHOT, зона = удаленная}]
- Установить его
> установщик установить композит: service_test
> Hello world !!!!
- Мы получаем наше первое сервисное сообщение. На самом деле, клиентский пакет загружается в клиент JVM.
- Проверить связки
На клиентской консоли введите:
>eq ss
.....
109 RESOLVED impl-1.0-SNAPSHOT_1.0.0.SNAPSHOT
110 RESOLVED org.springframework.bundle.osgi.io_1.2.0.m1
111 RESOLVED org.springframework.bundle.osgi.core_1.2.0.m1
112 RESOLVED org.springframework.bundle.osgi.extensions.annotations_1.2.0.m1-SNAPSHOT
113 ACTIVE org.springframework.bundle.osgi.extender_1.2.0.m1
114 ACTIVE client-1.0-SNAPSHOT_1.0.0.SNAPSHOT
Пакет Impl также загружен, но не запущен. Пакет Impl загружается, потому что он экспортирует интерфейсы API .
На консоли сервера введите:
> eq ss
....
108 ACTIVE impl-1.0-SNAPSHOT_1.0.0.SNAPSHOT
109 RESOLVED org.springframework.bundle.spring_2.5.5
110 RESOLVED org.springframework.bundle.osgi.io_1.2.0.m1
111 RESOLVED org.springframework.bundle.osgi.core_1.2.0.m1
112 RESOLVED org.springframework.bundle.osgi.extensions.annotations_1.2.0.m1-SNAPSHOT
113 ACTIVE org.springframework.bundle.osgi.extender_1.2.0.m1
114 ACTIVE com.sun.jini.browser_2.1.0
Примечание. Реализация развернута на сервере и активирована.
Примечание. Если мы разделили impl на два пакета api и impl , будет загружен только пакет api, и может возникнуть исключение RMI.
Вывод :
- В следующем выпуске OSGii 4.2 рекомендуется использовать функции Apache CXF и JEE.
- SCA делает общение простым без необходимости знать протоколы связи, издательские услуги и потребление декларативным способом.
исходный код опубликован в разделе svn:
svn checkout
http://hellosca.googlecode.com/svn/trunk/hellosca-read-only