Weitere ähnliche Inhalte
Ähnlich wie OUGF - Nouveautés OSGi Core 4.3
Ähnlich wie OUGF - Nouveautés OSGi Core 4.3 (20)
OUGF - Nouveautés OSGi Core 4.3
- 1. Nouveautés OSGi Core 4.3
OSGi Users’ Group France
Jeudi 24 novembre 2011
François Fornaciari - francois.fornaciari@zenika.com
Zenika © 2011 1
- 2. Historique
OSGi Specifications
Core (v4.3): plateforme minimale
Compendium (v4.2) : services additionnels
Enterprise (v4.2) : services orientés « entreprise »
OSGi Core 4.3 : mars 2011
Implémentations open-source
Eclipse Equinox 3.7 (Indigo)
Première livraison stable mars 2011
C’est la RI !
Apache Felix 4
Première livraison stable fin septembre 2011
Zenika © 2011 2
- 3. <Generics>
Introduction
Meilleure lisibilité du code
Meilleur typage des objets
Compatibilité avec le JRE 1.4
Utilisation de l’option de compilation -target jsr14
N’est pas une solution au code contenant des annotations dont la
RetentionPolicy est à RUNTIME
Configuration Maven
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>jsr14</target>
</configuration>
</plugin>
Zenika © 2011 3
- 4. <Generics>
Enregistrement de service
Avant OSGi 4.3
PrintService service = new PrintServiceImpl();
Properties props = new Properties();
props.put("color", "true");
bundleContext.registerService(PrintService.class.getName(), service, props);
OSGi 4.3
bundleContext.registerService(PrintService.class, service, props);
Comptabilité
Zenika © 2011 4
- 5. <Generics>
Recherche de service
Avant OSGi 4.3
ServiceReference reference =
bundleContext.getServiceReference(PrintService.class.getName());
PrintService service = (PrintService) bundleContext.getService(reference);
OSGi 4.3
ServiceReference<PrintService> reference =
bundleContext.getServiceReference(PrintService.class);
PrintService service = bundleContext.getService(reference);
Comptabilité
Zenika © 2011 5
- 6. <Generics>
ServiceTracker (1/2)
Avant OSGi 4.3
ServiceTracker serviceTracker =
new ServiceTracker(bundleContext,
PrintService.class.getName(),
null) {
public Object addingService(ServiceReference ref) {
// Méthode appelée lors de l'ajout au tracker d'un service satisfaisant le filtre
// Avantage : appelée à l'ouverture du tracker pour chaque service déjà enregistré
// Retourne un objet associé au service tracké (généralement le service détecté)
return super.addingService(reference);
}
public void modifiedService(ServiceReference ref, Object service) {
// Méthode appelée lors de la modification des propriétés d'un service tracké
}
public void removedService(ServiceReference ref, Object service) {
// Méthode appelée lors du retrait d'un service tracké
// Avantage : appelée à la fermeture du tracker pour chaque service tracké
}
};
serviceTracker.open();
PrintService service = (PrintService) serviceTracker.getService();
Zenika © 2011 6
- 7. <Generics>
ServiceTracker (2/2)
OSGi 4.3
ServiceTracker<PrintService, PrintService> serviceTracker =
new ServiceTracker<PrintService, PrintService>(bundleContext,
PrintService.class,
null) {
public PrintService addingService(ServiceReference<PrintService> ref) {
return super.addingService(reference);
}
public void modifiedService(ServiceReference<PrintService> ref,
PrintService s) {
}
public void removedService(ServiceReference<PrintService> reference,
PrintService s) {
}
};
serviceTracker.open();
PrintService service = serviceTracker.getService();
Zenika © 2011 7
- 8. <Generics>
ServiceFactory
Création d'un nouveau service à chaque lookup
Le service créé est associé au bundle consommateur
Un bundle récupérant deux fois le service reçoit la même instance
public class PrintServiceFactory implements ServiceFactory<PrintService> {
public PrintService getService(Bundle b, ServiceRegistration<PrintService> sr) {
return new PrintServiceImpl();
}
public void ungetService(Bundle b, ServiceRegistration sr, PrintService ps) {
}
}
[...]
// Enregistrement du service
bundleContext.registerService(PrintService.class, new PrintServiceFactory() , null);
[...]
// Client
PrintService service =
bundleContext.getService((bundleContext.getServiceReference(PrintService.class)));
Zenika © 2011 8
- 9. <Generics>
BundleTracker (1/2)
Avant OSGi 4.3
BundleTracker bundleTracker =
new BundleTracker(bundleContext, Bundle.ACTIVE, null) {
public Object addingBundle(Bundle bundle, BundleEvent event) {
// Méthode appelée lors de l'ajout au tracker d'un bundle satisfaisant l'état spécifié
// Avantage : appelée à l'ouverture du tracker pour chaque bundle déjà installé
// Retourne un objet associé au bundle tracké
[...]
return object;
}
public void removedBundle(Bundle bundle, BundleEvent event, Object o) {
// Méthode appelée lors du retrait d'un des bundles trackés
// Possibilité d'effectuer des traitements sur l'objet associé au bundle
// Avantage : appelée à la fermeture du tracker pour chaque bundle tracké
}
};
bundleTracker.open();
Zenika © 2011 9
- 10. <Generics>
BundleTracker (2/2)
OSGi 4.3
BundleTracker<String> bundleTracker =
new BundleTracker<String> (bundleContext, Bundle.ACTIVE, null) {
public String addingBundle(Bundle bundle, BundleEvent event) {
// Méthode appelée lors de l'ajout au tracker d'un bundle satisfaisant l'état spécifié
// Avantage : appelée à l'ouverture du tracker pour chaque bundle déjà installé
// Retourne un objet associé au bundle tracké
[...]
return "Objet tracké de type String";
}
public void removedBundle(Bundle bundle, BundleEvent event, String o) {
// Méthode appelée lors du retrait d'un des bundles trackés
// Possibilité d'effectuer des traitements sur l'objet associé au bundle
// Avantage : appelée à la fermeture du tracker pour chaque bundle tracké
}
};
bundleTracker.open();
Zenika © 2011 10
- 11. Capabilities & Requirements
Introduction
Jusqu’à présent le framework s’occupait de la résolution
des bundles en faisant correspondre des packages
importés avec des packages exportés
Depuis OSGi 4.3, généralisation des concepts de
dépendances
Un bundle peut offrir un Capability personnalisable
Un bundle peut exprimer une dépendance vers au travers d’un
Requirement
Prise en compte lors de la résolution d’un bundle
Permet de définir des dépendances qui ne sont pas des
dépendances de code
Ex : nombre minimal de cœurs CPU
Zenika © 2011 11
- 12. Capabilities & Requirements
Définition (1/2)
Capability
Un set d’attributs (couple clé/valeur) associé à un namespace
Requirement
Un filtre sur des attributs appartenant à un namespace
Namespace réservés
osgi.wiring.package
Import-Package, DynamicImport-Package et Export-Package
osgi.wiring.bundle
Require-Bundle, Bundle-SymbolicName et Bundle-Version
osgi.wiring.host
Fragment-Host, Bundle-SymbolicName et Bundle-Version
Zenika © 2011 12
- 13. Capabilities & Requirements
Définition (2/2)
Déclaration de le fichier MANIFEST
Capability
Provide-Capability: com.zenika.formation; year:Long=2011; effective:=resolve
Requirement (filtre LDAP)
Require-Capability: com.zenika.formation; filter:="(year=2011)"
Déclaration de l’environnement d’exécution requis
Avant OSGi 4.3 (déprécié)
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
OSGi 4.3
Require-Capability: osgi.ee;filter:="(&(osgi.ee="JavaSE")(version>=1.6))"
Zenika © 2011 13
- 14. Core Services
Package Admin Service
Start Level Service
Conditionnal Permission Service
Bundle Wiring API
Start Level API
Service Hook Service
Resolver Hook Service
Weaving Hook Service
URL Handler Services
Remote Services
Zenika © 2011 14
- 15. Package Admin Service
Rappel
Service permettant d'analyser et d'agir sur les
dépendances
Zenika © 2011 15
- 16. Start Level Service
Rappel
Service permettant de gérer la séquence d'activation des
bundles
Zenika © 2011 16
- 17. Deprecated services
« Package Admin Service » et « Start Level Service » sont
dépréciés
Utilisés par les outils d’administration de plateformes OSGi
Shells OSGi
Console de management web de Felix
Servers d’applications
Etc.
Zenika © 2011 17
- 18. Nouveaux services OSGi 4.3
Remplacement de « Package Admin Service » par
« Bundle Wiring API » et de « Start Level Service » par
« Start Level API »
A l'origine, choix d'une approche orientée service
(dynamique) mais ce design n'était pas suffisamment
orienté objet (passage de l'objet bundle à chaque méthode)
Nouvelle représentation des « Wiring » entre bundles en se
basant sur l’introduction des concepts de « Capability » et
« Requirement »
Zenika © 2011 18
- 19. Bundle Wiring API (1/4)
A chaque résolution de bundle, un objet de type
BundleWiring est créé pour une révision donnée
A noter : chaque mise à jour d'un bundle déclenche la création
d'une nouvelle révision. Seule une opération de « refresh » permet
de forcer la rafraichissement des liaisons entre les bundles
Permet de récupérer les informations de dépendance
Nom symbolique, version, etc.
Packages requis / fournis, fragments, etc.
Représentation des liaisons au « runtime »
Zenika © 2011 19
- 21. Bundle Wiring API (3/4)
Exemple de récupération des packages importés
BundleWiring bundleWiring =
bundleContext.getBundle().adapt(BundleWiring.class);
for (BundleWire wire : bundleWiring.getRequiredWires("osgi.wiring.package")) {
String packageName =
(String) wire.getCapability().getAttributes().get("osgi.wiring.package");
Bundle bundle = wire.getProviderWiring().getBundle();
[...]
}
Namespaces osgi.wiring.bundle et osgi.wiring.host
List<BundleCapability> capabilities = bundleWiring.getCapabilities(null);
for (BundleCapability bundleCapability : capabilities) {
System.out.println(bundleCapability.toString());
}
// En sortie de la console
osgi.wiring.bundle; osgi.wiring.bundle="zenika-bundle"; bundle-version:Version="1.0.0"
osgi.wiring.host; osgi.wiring.host="zenika-bundle"; bundle-version:Version="1.0.0"
Zenika © 2011 21
- 22. Bundle Wiring API (4/4)
Collection<String> resources =
bundleWiring.listResources("/", "*.properties",
BundleWiring.LISTRESOURCES_RECURSE);
Collection<URL> resources =
bundleWiring.findEntries("/", "*.class",
BundleWiring.FINDENTRIES_RECURSE);
Zenika © 2011 22
- 23. Start Level API
Manipulation des informations de « StartLevel »
BundleStartLevel bundleStartLevel =
bundleContext.getBundle().adapt(BundleStartLevel.class);
int startLevel = bundleStartLevel.getStartLevel();
Opérations à partir du « System Bundle »
FrameworkStartLevel frameworkStartLevel =
bundleContext.getBundle(0).adapt(FrameworkStartLevel.class);
int initialBundleStartLevel = frameworkStartLevel.getInitialBundleStartLevel();
Zenika © 2011 23
- 24. Service Hook
Rappel (1/2)
Spécification permettant d'interagir avec le « service
engine » : depuis OSGi 4.2
Connaître les services requis par les bundles
Limiter la visibilité de certains services
Mettre facilement en œuvre des proxies de services
Trois types d'interactions
Event Hook : intercepte les évènements liés au cycle de vie des
services (enregistrement / désenregistrement / modification)
Filtrer tout ou partie des évènements reçus par les bundles
Find Hook : intercepte la recherche de références de services
Manipuler les références de services demandées
Listener Hook : intercepte la création et la suppression de
ServiceListener
Avoir la connaissance des services potentiellement utilisés par les bundles
Zenika © 2011 24
- 25. Service Hook
Rappel (2/2)
public interface EventHook {
// contexts : contextes vers lesquels les évènements sont propagés
// (peuvent être modifiés)
void event(ServiceEvent event, java.util.Collection contexts);
}
public interface FindHook {
// allServices : filtre sur getServiceReferences()
// ou getAllServiceReferences()
void find(BundleContext context, java.lang.String name,
java.lang.String filter, boolean allServices,
java.util.Collection references);
}
public interface ListenerHook {
void added(java.util.Collection listeners);
void removed(java.util.Collection listeners);
}
Zenika © 2011 25
- 26. Nouvelles interceptions (1/2)
Ajout de trois nouveaux mécanismes d'interception depuis
la version 4.3
Weaving Hook
Permet d'intercepter le chargement de classe des bundles et de
manipuler le bytecode avant chargement
Les nouvelles classes générées peuvent dépendre de nouvelles
classes, d'où la possibilité de modifier au runtime l'attribut
DynamicImport-Package du fichier MANIFEST
Resolver Hook
Permet d'intercepter le mécanisme de résolution de packages et
d'influencer le resolver
Exemple : limiter la visibilité de certains packages
Zenika © 2011 26
- 27. Nouvelles interceptions (2/2)
Bundle Hook
Permet d'intercepter les évènements du framework à propos du
cycle de vie des bundles (Event Hook)
Permet de limiter la visibilité de certains bundles (Find Hook)
Le trio «Service Hook », « Resolver Hook » et « Bundle
Hook » offre un mécanisme efficace pour introspecter le
framework et agir sur son comportement
Cas d'utilisation : isoler plusieurs applications s'exécutant sur le
même framework
Alternative aux mécanismes de sécurité offerts par la plateforme
Zenika © 2011 27
- 28. Resolver Hook Service
Mise en œuvre
Enregistrement d'un service de type ResolverHookFactory
A chaque tentative de résolution d'un bundle par le
framework, création d'une instance de ResolverHook
Possibilité de filtrer la résolution d'un bundle ou la
résolution de packages spécifiques
Zenika © 2011 28
- 29. Bundle Hook Service
Mise en œuvre
Event Hook : intercepte les évènements liés au cycle de vie
des bundles (install / start / update / …) avant de les
émettre aux différents listeners
Filtrer les évènements reçus par les bundles
Find Hook : intercepte les appels aux méthodes de
récupération des bundles présents sur la plateforme
Manipuler la liste de bundles retournées
Zenika © 2011 29
- 30. Virgo regions
Eclipse Virgo 3.0 s’appuie sur les mécanismes
d’interception pour créer des régions isolées
Précédemment implémentées par les « nested framework »
qui ont été abandonnés
Plan de contribution des régions dans Equinox
Zenika © 2011 30
- 31. Ressources
Spécifications OSGi
http://www.osgi.org
OSGi Wiki
http://en.wikipedia.org/wiki/OSGi
Billets de blog
http://jaxenter.com/what-s-new-in-core-4-3-36450.html
http://www.infoq.com/news/2011/03/osgi-43
Zenika © 2011 31