Do published OSGI services need to have their packages exported? - osgi

Do the packages that contain OSGI services need to be exported in order to publish to the service registry? Or does publishing to the service registry get round the need to export the package?

Short answers; 1st question = no, 2nd question = no, there's no "workaround"
The principle of "Design by contract" comes into play. Basically we provide an interface for consumers to depend on and providers to implement - this decouples our consumer code for the implementation details of our implementors. See http://www.osgi.org/blog/2011/08/package-as-contract.html for a good overview and http://en.wikipedia.org/wiki/Design_by_contract.
Given the interface (the API we wish to use) and the implementation (the concrete implementation of the API interface) and the consumer (code wishing to use an implementation of the interface), with OSGi you have a number of options.
A bundle can provide both interface and implementation, but it must export the interface if this service is to be used outside of the bundle itself
Having a separate bundle for the interface (which it exports) and other bundle(s) for the implementation(s) - the implementing bundles must import the interface's package but need not reveal their own implementation.
The advantages of number 2 include allowing multiple providers (OSGi uses LDAP filters that can be used to specify metadata matching on the registered services' properties), and leveraging the dynamic binding nature of OSGi (i.e. you can change implementation provider at runtime).
One thing to bear in mind, is that the consumer and provider must use the same classes as defined by the package version and exporting bundle (in other words the bundle classloader that loads the API classes must be the same for both consumer and provider).

The types of the service should be in exported packages. Services are typed and build upon the type sharing of the module layer. So you need to make sure that the provider of the service and the consumers of the service can all share the same type. So some bundle must export the package containing the type so that the provider and the consumers can import the package. This allows the framework to verify type safety of the service.

Related

Create A Service And Allow Only One Bundle To Hold That Service At any Time

I'm trying to create a service such that once it is created it only allows itself to be held by a single consumer/bundle at any one time. (If this is against the philosophy/specification of OSGi then that obviously provides a quick answer but reference to the OSGi specs. stating this would be appreciated.)
To implement such a requirement I implemented the ServiceFactory interface thinking that whenever there was a requirement for the service the getService(Bundle bundle, ServiceRegistration<S> registration) method would be called and it would be where I could determine if the Bundle was a new consumer or not and act accordingly.
It appears that this is not the case in the scenario I have tested this in.
Using a Apache Karaf and instantiating a consumer of the Service via Blueprint it would seem that the getService method is never called. Instead the consumer's binding method for the service is called directly but injecting a proxy service object.
While I understand that Blueprint uses proxies surely there is still the obligation of the ServiceFactory contract to fulfil even if it's a proxy object consuming the service?
Why do I want to do this?
I am attempting to wrap JavaFX and the Stage class and because JavaFX isn't OSGi friendly I am attempting to co-ordinate access to the Stage object. I'm aware that there are frameworks such as Drombler but a brief look at them made me think that it doesn't suit my use case. They appear too restrictive for my needs e.g. I don't necessarily wish to layout an application in the manner Drombler uses.
It depends what you mean by a consumer. ServiceFactory does give you the chance to create a separate instance of a service per bundle that calls getService on your service. It's not clear from your question but I suspect you weren't seeing the getService invoked multiple times because you were fetching the service from the same consumer bundle. In this case, ServiceFactory simply returns the same object repeatedly.
As for your general question about restricting access to a single consumer, no that really goes against the OSGi philosophy. I'm sorry I don't have a spec reference for you but the clue is in the name: it's a service that is available to all.
I'm aware that there are frameworks such as Drombler but a brief look at them made me think that it doesn't suit my use case. They appear too restrictive for my needs e.g. I don't necessarily wish to layout an application in the manner Drombler uses.
Please note that the layout of Drombler FX applications is pluggable so you can provide your own implementation tailored to your needs. This allows you to get the most out of Drombler FX and JavaFX.
While this feature is available for some time, there is now a new tutorial trail explaining it in more detail.

OSGi: when to use component framework and when to create objects yourself

I've been an AEM developer for almost a year now. I know AEM uses 'Declarative Services component framework' to manage life cycle of OSGi components.
Consider a scenario when i would export a package from a bundle and import that package from another bundle, i could create objects of classes in first bundle inside second bundle as well. it's a import-export contract in this case.
my question is when i should be using component framework to manage the lifecycle of my objects and when to handle it myself by creating them when required.
In an ideal design, you would NOT in fact be able to create objects from the exported package; because that package would contain only interfaces. This makes it a "pure" contract (API) export. If there are classes in there that you can directly instantiate, then they are implementation classes.
In general it is far better to export only pure APIs and to keep implementation classes hidden. There are two main reasons:
Implementation classes tend to have downstream dependencies. If you depend directly from implementation class to implementation class then you get a very large and fragile dependency graph... and eventually that graph will contain a cycle. In fact it's almost inevitable that it will. At that point, your application is not modular because you cannot deploy or change any part of it independently.
Pure interfaces can be analysed for compatibility between versions. As a consumer or a provider of an API, you know exactly which versions of the API you can support because the API does not contain executable code. However if you have a dependency onto an implementation class, then you never really know when they break compatibility because the breakage could happen deep down in executable code that you can't easily analyse.
If your objects are services then there's no question, they have to be OSGi components.
For other things, my first choice is OSGi components, unless they're trivial objects like data holders or something similar.
If an object requires configuration or refers to OSGi services then it's also clearly an OSGi component.
In general, it's best IMO to think in services and define your package exports as the minimum that allows other bundles to use a bundle's services. Unless a bundle is clearly a reusable library like commons-io (to take a simple example).

Obtaining list of installed OSGI bundles at runtime

My application obtains class names from a properties file. Classes represented by these class names could reside in certain OSGI bundles unknown at advance so in order to instantiate them I firstly have to find which bundle these classes belong to. I'm thinking about getting all installed bundles from BundleContext#getBundles, this means I have to obtain reference to BundleContext in AbstractUIPlugin#start. But I'm not sure if holding reference to BundleContext is the right thing to do since it's should be used only in the start method. So I need advice from OSGI experts here about the alternatives to get list of bundles.
Any help would be greatly appreciated.
Regards,
Setya
This is not really how OSGi is intended. If a bundle has something to add to the 'global' context, you should register a service. So each bundle that has something to share can do that in its own start method.
Some other component (DS, ServiceTracker, Blueprint, something like that) can then listen to these events, and act accordingly.
This is really important, if you start manually searching through all bundles you completely lose the advantages of OSGi.
Like written before you should try to use services to achieve what you want. I guess you have an Interface with one or more implementations that should be installable at runtime. So if you control the bundles that implement the interface then simply let them install their implementation as a service by using an Activator or a blueprint context. You can use service properties to describe your implementation.
The bundles that need the implementation can then lookup the services using a service tracker or a service reference in blueprint.
If that is not possible then you can use the bundle context to obtain the running bundles and instantiate the classes but this is not how OSGi should work. You will run into classloading problems as the bundle that tries to instantiate the classes will not have direct access to them.
Your bundle gets control at start up through the bundle activator, or better, through DS. At that time it can register services with the services registry so others can find/use them.
The route your planning to go (properties that name classes) is evil since you undoubtedly will run in class loading hell. Modularity is about hiding your implementation details, the name of your implementation classes are such details.
Exposing implementation classes in properties files is really bad practice and it looses the advantage of modularity. It does not matter if another class refers to your implementation class or a property file, the problem is that the impl. class is exposed.
Unfortunately this model has become so prevalent in our industry that many developers think it is normal :-(
OSGi allows you share instances typed by interfaces in a way that allows the implementation class to only be known inside the module.

Is separate OSGI bundles for api and implementation common practice?

I have a class with dependencies which I want to hot deploy without restarting the dependencies. The class has an interface but there's only one concrete implementation.
Initially I created a single bundle with exported the interface and registered the implementation using activator and implementation classes which were not exported. However, if I update the bundle, bundles which use the registered service get restarted after the update when PackageAdmin#refreshPackages is called (this is automatic when using fileinstall).
I have fixed this by creating a separate api bundle.
Is this the best way to achieve this?
Would you ever have a bundle which exports its api and includes the implementation in the same bundle. As far as I can see any give bundle would either export all its classes or no classes. What am I missing?
It is definitely a best practice to separate API bundles from their implementations in OSGi. If you do this, then any bundle that uses the API only needs to import classes from the API bundle, which can allow you to change implementations at runtime without restarting your dependent bundles.
Ideally your implementation bundle would implement the interface and export implementation as a service on the API provided interface. This allows the client bundles to utilize the service without referencing the implementation bundle.
In Apache Sling we do both: major APIs are in their own bundles, but for smaller things like extensions or optional components we often provide the default implementation in the same bundle as the API.
In the latter case, you can still allow for those default services to be replaceable, for example using service ranking values when you want to override them.
A bundle does not have to export all its classes, our bundles which include default services export just the API packages (and the default implementations are in different packages, obviously).
Unless there is a hard requirement to be able to replace implementation at runtime, without restarting client bundles, I would personally advocate keeping the explicit dependency link between API and implementation (either by including impl classes in the API bundle, or by having the API bundle import implementation packages from the impl. bundle).
The pb with the patterns suggested above is that they break the dependency chain. The benefits of dependency management go far beyond simple API compatibility, they also include ensuring predictable, consistent runtime behavior, as well as compatibility with the deployment ecosystem, and all of those require managing the implementation dependencies.

Knopflerfish packaging

I am at the moment creating a matrix which is showing how far Knopflerfish, Equinox and Felix are OSGi 4.2 compliant.
So far I looked at the Knopflerfish documentation (Link 1, Link 2) to get an idea of how much of the Core and Compendium specs are actually implemented.
The core specification seems to be fully implemented, although there are some inconsistent statements about the Security Layer and the Declarative Services.
What makes me wonder is how much of all the Compendium specs are implemented:
Remote Services
Log Service
Http Service
Device Access
Configuration Admin Service
Metatype Service
Preferences Service
User Admin Service
Wire Admin Service
IO Connector Service
Initial Provisioning
UPnP Device Service
Declarative Services
Event Admin Service
Deployment Admin
Auto Configuration
Application Admin
DMT Admin Service
Monitor Admin Service
Foreign Application Access
Blueprint Container
Tracker
XML Parser Service
Position
Measurement and State
Execution Environment
To find out more I downloaded (Download page) the source code of Knopflerfish and had a look at it. It looks like some parts of the spec are implemented through the "original" framework provided by the OSGi Alliance (org.osgi.*).
One example is the UPnP package:
alt text http://img6.imageshack.us/img6/5853/screenshot20100403at212.png
Does this mean that missing parts which are not directly implemented by Knopflerfish are added through the "original" OSGi framework?
And does this also apply to other frameworks like Felix or Equinox?
Most of the OSGi specifications define interface classes for services. You can download these classes together with the specification directly from the OSGi Alliance's website.
Implementations such as Knopflerfish must provide the underlying functionalities, e.g. the actual implementation for the UPnP Service Admin you mentioned in your example. Some of the interface classes also provide interfaces that must be implemented by the developer of a user service, e.g. a BundleActivator.
All frameworks that claim to be OSGi compliant must provide implementations for these interfaces. There is no "original" OSGi framework (well, beside of the reference implementation, of course). The interfaces do not provide implementations.

Resources