The Security Layer is based on Java 2 security but adds a number of constraints and fills in some of the blanks that standard Java leaves open.
czy
The Module Layer defines a modularization model for Java. It addresses some of the shortcomings of Java’s deployment model
Co jest interesującego w OSGi to fakt, że związany jest nierozerwalnie z wirtualną maszyną Javy (JVM) dodając do niej dodatkowe elementy-warstwy usprawniające, czyli co w zamyśle autorów OSGi wymagało usprawnienia, jak dodanie mechanizmu zabiezpieczania dostępu do wybranych elementów (pakietów) aplikacji czy możliwości ich włączania/wyłączania dynamicznie w trakcie pracy. Właśnie możliwości włączania/wyłączania opisane są w rozdziale 4. Warstwa rozwojowa (Life Cycle Layer), któremu się przyjrzę pokrótce.
Warstwa rozwojowa (ang. Life Cycle Layer) dostarcza interfejs programistyczny API do kontrolowania bezpieczeństwa i cyklu rozwojowego pakunków. Do poprawnego działania wymaga współpracy z warstwami modułową i bezpieczeństwa. O pierwszej można było przeczytać w mojej notatce - Kolejny łyk OSGi - rozdział 3. Warstwa modułowa.
Integralne cechy warstwy rozwojowej:
- Warstwa rozwojowa musi dostarczać implementację API do zarządzania etapami rozwojowymi pakunków.
- Udostępnia mechanizm prześwietlenia (sprawdzania) stanu platformy i jej pakunków.
- Udostępnia API do szczegółowego określania uprawnień (warstwa bezpieczeństwa jest opcjonalna).
- Zarządzanie zdalne
- Pakunek (ang. bundle) - podstawowy moduł usługowy
- Kontekst (wykonawczy) pakunku (ang. bundle context) w ramach platformy OSGi, który jest przekazywany do aktywatora pakunku (ang. bundle activator) podczas uruchamiania/zatrzymywania pakunku.
- Aktywator pakunku (ang. bundle activator) - interface implementowany przez klasę w pakunku, która służy do jego uruchomienia bądź zatrzymania.
- Zdarzenie pakunkowe (ang. bundle event) - zdarzenie, które sygnalizuje zmianę etapu rozwojowego w cyklu rozwojowym pakunku. Zdarzenie obsługiwane jest przez (synchronicznego) słuchacza pakunku (ang. bundle listener).
- Zdarzenie OSGi (szkieletowe) (ang. framework event) - zdarzenie, które syngalizuje błąd lub zmianę stanu szkieletu OSGi. Zdarzenie obsługiwane jest przez (synchronicznego) słuchacza Szkieletu OSGi (ang. framework listener).
- Słuchacz pakunku (ang. bundle listener) - obiekt nasłuchujący zmian rozwojowych pakunku, obsługujący zdarzenia pakunkowe
- Słuchacz szkieletowy (ang. Framework listener) - obiekt nasłuchujący błędów lub zmian stanu Szkieletu OSGi, obsługujący zdarzeń platformy OSGi.
- Wyjątek pakunkowy (ang. bundle exception) - wyjątek zgłoszony jako wynik wystąpienia błędu podczas wykonania operacji OSGi
- Pakunek systemowy (ang. system bundle) - pakunek reprezentujący Szkielet OSGi
Instalacja pakunku może być wykonana wyłącznie przez inny pakunek lub za pomocą mechanizmów specyficznych dla implementacji platformy OSGi (polecenie install w Felix oraz Equinox).
jlaskowski@dev /cygdrive/c/apps/felixlub
$ java -jar bin/felix.jar
Welcome to Felix.
=================
Enter profile name: sandbox
DEBUG: WIRE: 1.0 -> org.osgi.service.packageadmin -> 0
DEBUG: WIRE: 1.0 -> org.osgi.service.startlevel -> 0
DEBUG: WIRE: 1.0 -> org.ungoverned.osgi.service.shell -> 1.0
DEBUG: WIRE: 1.0 -> org.osgi.framework -> 0
DEBUG: WIRE: 1.0 -> org.apache.felix.shell -> 1.0
DEBUG: WIRE: 2.0 -> org.osgi.framework -> 0
DEBUG: WIRE: 2.0 -> org.apache.felix.shell -> 1.0
DEBUG: WIRE: 3.0 -> org.osgi.service.obr -> 3.0
DEBUG: WIRE: 3.0 -> org.osgi.framework -> 0
-> DEBUG: WIRE: 3.0 -> org.apache.felix.shell -> 1.0
-> help
bundlelevel <level> <id> ... | <id> - set or get bundle start level.
cd [<base-URL>] - change or display base URL.
headers [<id> ...] - display bundle header properties.
help - display impl commands.
install <URL> [<URL> ...] - install bundle(s).
obr help - OSGi bundle repository.
packages [<id> ...] - list exported packages.
ps [-l | -s | -u] - list installed bundles.
refresh [<id> ...] - refresh packages.
resolve [<id> ...] - attempt to resolve the specified bundles.
services [-u] [-a] [<id> ...] - list registered or used services.
shutdown - shutdown framework.
start <id> [<id> <URL> ...] - start bundle(s).
startlevel [<level>] - get or set framework start level.
stop <id> [<id> ...] - stop bundle(s).
uninstall <id> [<id> ...] - uninstall bundle(s).
update <id> [<URL>] - update bundle.
version - display version of framework.
jlaskowski@dev /cygdrive/c/apps/eclipsePakunek uruchamiany jest przez swojego aktywatora, który zdefiniowany jest w manifeście za pomocą nagłówka Bundle-Activator. Aktywator pakunku implementuje interfejs org.osgi.framework.BundleActivator. Jedynie pojedyńczy aktywator może zostać zdefiniowany dla pakunku (ale nie dla pakunku częściowego - ang. fragment bundles, który nie może mieć ich wcale).
$ java -jar plugins/org.eclipse.osgi_3.4.0.v20080205.jar -console
osgi> help
---Controlling the OSGi framework---
launch - start the OSGi Framework
shutdown - shutdown the OSGi Framework
close - shutdown and exit
exit - exit immediately (System.exit)
init - uninstall all bundles
setprop <key>=<value> - set the OSGi property
---Controlling Bundles---
install - install and optionally start bundle from the given URL
uninstall - uninstall the specified bundle(s)
start - start the specified bundle(s)
stop - stop the specified bundle(s)
refresh - refresh the packages of the specified bundles
update - update the specified bundle(s)
---Displaying Status---
status [-s [<comma separated list of bundle states>] [<segment of bsn>]] - display installed bundles and registered services
ss [-s [<comma separated list of bundle states>] [<segment of bsn>]] - display installed bundles (short status)
services [filter] - display registered service details
packages [<pkgname>|<id>|<location>] - display imported/exported package details
bundles [-s [<comma separated list of bundle states>] [<segment of bsn>]] - display details for all installed bundles
bundle (<id>|<location>) - display details for the specified bundle(s)
headers (<id>|<location>) - print bundle headers
log (<id>|<location>) - display log entries
---Extras---
exec <command> - execute a command in a separate process and wait
fork <command> - execute a command in a separate process
gc - perform a garbage collection
getprop [ name ] - displays the system properties with the given name, or all of them.
---Controlling Start Level---
sl [<id>|<location>] - display the start level for the specified bundle, or for the framework if no bundle specified
setfwsl <start level> - set the framework start level
setbsl <start level> (<id>|<location>) - set the start level for the bundle(s)
setibsl <start level> - set the initial bundle start level
---Controlling the Profiling---
profilelog - Display & flush the profile log messages
---Eclipse Runtime commands---
diag - Displays unsatisfied constraints for the specified bundle(s).
enableBundle - enable the specified bundle(s)
disableBundle - disable the specified bundle(s)
disabledBundles - list disabled bundles in the system
---Controlling the Console---
more - More prompt for console output
osgi> exit
Interfejs BundleActivator dostarcza metod start() oraz stop() odpowiednio do uruchomienia i zatrzymania pakunku. W ten sposób dostawca pakunku może wpłynąć (zmodyfikować) domyślny proces uruchamiania/zatrzymywania pakunku. Szkielet OSGi gwarantuje, że poprawne wykonanie metody start() implikuje wykonanie metody stop() na tym samym egzamplarzu pakunku. Zabrania się, aby Szkielet OSGi wykonywał metody aktywatora wielowątkowo. Podczas uruchomienia/zatrzymania pakunku przkazywany jest kontekst wykonania w postaci obiektu org.osgi.framework.BundleContext, który dostarcza informacje o stanie środowiska wykonawczego OSGi, możliwość zainstalowania innych pakunków oraz dostęp do rejestru usług (pakunków).
Przyjrzyjmy się przykładowemu pakunkowi ze zdefiniowanym aktywatorem. Wesprę się Mavenem 2 do zarządzania projektem i wtyczką maven-bundle-plugin. Działanie wtyczki opisałem w artykule Pakunki OSGi w projekcie wielomodułowym Apache Maven 2 z maven-bundle-plugin.
jlaskowski@dev /cygdrive/c/projs/osgiImport do Eclipse 3.4M5 z pomocą wtyczki m2eclipse (tym razem do Eclipse) i modyfikacja pom.xml o wpisy dotyczące wtyczki maven-bundle-plugin (ta wspomniana od Maven2). Ostatecznie plik pom.xml wygląda następująco:
$ mvn archetype:create -DgroupId=pl.jaceklaskowski.osgi -DartifactId=osgi-lifecycle -Dversion=1.0
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [archetype:create] (aggregator-style)
[INFO] ------------------------------------------------------------------------
...
[INFO] OldArchetype created in dir: c:\projs\osgi\osgi-lifecycle
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"Tworzę klasę aktywatora pakunku, który nie robi nic poza wypisaniem komunikatu o stanie prac:
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>pl.jaceklaskowski.osgi</groupId>
<artifactId>osgi-lifecycle</artifactId>
<packaging>bundle</packaging>
<version>1.0</version>
<name>osgi-lifecycle</name>
<url>http://www.jaceklaskowski.pl</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-Activator>${groupId}.AktywatorPakunku</Bundle-Activator>
<!-- Bez Private-Package pakunek (projekt) nie budował się -->
<Private-Package>${pom.groupId}.*</Private-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.osgi.core</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>
package pl.jaceklaskowski.osgi;Zbudowanie projektu, a tym samym i pakunku (skasowałem domyślnie tworzoną klasę App oraz jej test i zależność junit z pom i stąd tak skromnie przy uruchomieniu).
import java.util.logging.Logger;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class AktywatorPakunku implements BundleActivator {
Logger log = Logger.getLogger(AktywatorPakunku.class.getName());
public void start(BundleContext bundleContext) throws Exception {
log.info("start() wykonano - rozpoczynam pracę");
}
public void stop(BundleContext bundleContext) throws Exception {
log.info("stop() wykonano - czyszczę po sobie");
}
}
jlaskowski@dev /cygdrive/c/projs/osgi/osgi-lifecycleI pora na uruchomienie w środowisku Apache Felix:
$ mvn clean package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building osgi-lifecycle
[INFO] task-segment: [clean, package]
[INFO] ------------------------------------------------------------------------
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
jlaskowski@dev /cygdrive/c/projs/osgi/osgi-lifecycle
$ ls -l target/osgi-lifecycle-1.0.jar
-rwxr-xr-x+ 1 jlaskowski None 4009 Mar 25 22:37 target/osgi-lifecycle-1.0.jar
jlaskowski@dev /cygdrive/c/apps/felix
$ java -jar bin/felix.jar
Welcome to Felix.
=================
Enter profile name: osgi
DEBUG: WIRE: 7.0 -> org.osgi.service.packageadmin -> 0
DEBUG: WIRE: 7.0 -> org.osgi.service.startlevel -> 0
DEBUG: WIRE: 7.0 -> org.ungoverned.osgi.service.shell -> 7.0
DEBUG: WIRE: 7.0 -> org.osgi.framework -> 0
DEBUG: WIRE: 7.0 -> org.apache.felix.shell -> 7.0
DEBUG: WIRE: 8.0 -> org.osgi.framework -> 0
DEBUG: WIRE: 8.0 -> org.apache.felix.shell -> 7.0
DEBUG: WIRE: 9.0 -> org.osgi.service.obr -> 9.0
DEBUG: WIRE: 9.0 -> org.osgi.framework -> 0
-> DEBUG: WIRE: 9.0 -> org.apache.felix.shell -> 7.0
-> install file:c:/projs/osgi/osgi-lifecycle/target/osgi-lifecycle-1.0.jar
-> start 10
DEBUG: WIRE: 10.0 -> org.osgi.framework -> 0
2008-03-25 22:38:47 pl.jaceklaskowski.osgi.AktywatorPakunku start
INFO: start() wykonano - rozpoczynam pracŕ
-> stop 10
2008-03-25 22:38:52 pl.jaceklaskowski.osgi.AktywatorPakunku stop
INFO: stop() wykonano - czyszczŕ po sobie
Pytanie dla wytrwałych (całkowicie niezwiązane z OSGi acz zostało wykorzystane w tej notatce): Jaka jest różnica między wykonaniem polecenia mvn package a mvn install? Ponownie, nagrody nie ma.
Package tworzysz paczkę z projektu a robiąc install instalujesz ją w lokalnym repozytorium :)
OdpowiedzUsuńPozdrawiam,
Radek
No, żebyś mi nie wypominał, że nieprecyzyjnie to opisałem, to dodam jeszcze, że zainstalowana paczka jest dostępna dla innych projektów (zaciągają ją z naszego lokalnego repozytorium), można też w mavenie zrobić deploy i w ten sposób zainstalować paczkę w zdalnym repozytorium.
OdpowiedzUsuńTaka odpowiedź styknie? :D
Radek
Nie mógłbym wyobrazić sobie pełniejszej odpowiedzi. 5+!
OdpowiedzUsuńJacek
Fajnie, że wziąłeś się za opisywanie OSGi :)
OdpowiedzUsuńZauważyłem małą nieścisłość napisałeś "4. Warstwa modułowa (Life Cycle Layer)" zamiast 4. Warstwa rozwojowa (Life Cycle Layer).
Pozdrowienia :)
Poprawione. Dziękuję!
OdpowiedzUsuń