Hi,

AFAIK capabilities are used to resolve bundles. They will not help to restrict 
the referenced services. That means if you reference resource services of a 
special type in a consumer service, you can not specify which service should be 
injected by using capabilities.

For restricting the services that should be injected you can use the target 
reference property. The value is an LDAP filter that can inspect service 
properties to select the target services that should be referenced. So you 
could for example specify a version property on your services and specify a 
target filter in our consumer.

It is also possible to dynamically change the target filter using the 
Configuration Admin.

I wrote about this in one of my blog posts: 
http://blog.vogella.com/2016/09/26/configuring-osgi-declarative-services/

Mit freundlichen Grüßen / Best regards

 Dirk Fauth

Automotive Service Solutions, ESI application (AA-AS/EIS2-EU) 
Robert Bosch GmbH | Postfach 11 29 | 73201 Plochingen | GERMANY | www.bosch.com
Tel. +49 7153 666-1155 | dirk.fa...@de.bosch.com

Sitz: Stuttgart, Registergericht: Amtsgericht Stuttgart, HRB 14000; 
Aufsichtsratsvorsitzender: Franz Fehrenbach; Geschäftsführung: Dr. Volkmar 
Denner, 
Prof. Dr. Stefan Asenkerschbaumer, Dr. Rolf Bulander, Dr. Stefan Hartung, Dr. 
Markus Heyn, Dr. Dirk Hoheisel,
Christoph Kübel, Uwe Raschke, Peter Tyroller


-----Ursprüngliche Nachricht-----
Von: osgi-dev-boun...@mail.osgi.org [mailto:osgi-dev-boun...@mail.osgi.org] Im 
Auftrag von Mark Raynsford
Gesendet: Freitag, 26. Mai 2017 12:54
An: osgi-dev@mail.osgi.org
Betreff: [osgi-dev] Publishing resources with respect to versioning

Hello.

As stated previously, I'm working on a commercial (but open source) game 
project. I'm currently working on the code to load resources into the engine 
(the "resource manager"). A "resource" in this case can be more or less 
anything: Sounds, images, game levels, 3D models, compiled Java code, NPC 
definitions, etc. A major design requirement for the engine is to have a 
strongly versioned code and resource package system with proper dependency 
handling. Obviously, I'm delegating all of this work to OSGi.

Exposing Java code as services is obviously not a problem; we use declarative 
services and the like. However, I also wanted it to be possible to expose 
non-code resources in some manner. A while back, I was advised to use a 
BundleTracker to expose non-code resources inside bundles as services [0]. This 
works well enough, but the problem is that I'm not sure how to properly expose 
the services such that version constraints are respected.

For example, let's take a naive implementation: A bundle loaded into the game 
engine might have a file "/catalog.txt" listing the resources to be exported as 
services. Each entry in the catalog file declares a fully qualified name such 
as "com.example.images.brick", "com.example.sounds.zap", etc, and a file inside 
the bundle that will be associated with this name. Resources can depend on each 
other. For example, a definition for a new type of NPC might contain a list of 
references to sounds that that NPC uses. The NPC definition would refer to each 
sound by using its fully qualified name ("com.example.sounds.zap", for example).

A naive implementation might have a BundleTracker read this catalog file when 
the bundle is loaded and simply publish each named resource by instantiating a 
service for each and maintaining some sort of map that can associated fully 
qualified resource names with services. If a resource inside a bundle states 
that it depends on another resource called "com.example.sounds.zap", the 
resource manager just looks up the name in the map and returns a reference to 
the corresponding service.

The problem here should be immediately obvious: If two different versions of 
the same bundle are loaded then there are going to be naming conflicts. 
Resource defintions are essentially loaded into one big global namespace, and 
we essentially get DLL-hell for resources.
If a resource in bundle A specifies that it depends on a resource in bundle B, 
but a different version of bundle B (let's call it C) was loaded afterwards and 
essentially overrode the contents of B... Ouch.

A better implementation would take into account the dependency and version 
information included in the bundle manifest. So, for example, a bundle A might 
declare that it depends on bundle B, and the resource manager implementation 
would ensure that only the resources exported by B are visible to A. If another 
version of bundle B is loaded that has a version range incompatible with that 
specified by bundle A (let's call it bundle C), then A cannot see the resources 
published by C. Bundle A carries on referring to other resources using 
fully-qualified names as normal, and the underlying resource manager ensures 
that those names are mapped to those resources in bundle B from the perspective 
of A.

I'd like to implement this, but I feel like I'd more or less be reinventing 
OSGi on top of OSGi. Is there some way I can delegate all of this work back to 
OSGi's resolver? From what I can see, the capability system is designed to 
facilitate this sort of thing, but as it's relatively new, I can't find any 
good literature on how to apply it. I'm not sure if it's even appropriate to my 
needs.

M

[0] https://mail.osgi.org/pipermail/osgi-dev/2017-April/006312.html
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to