I just finished thoroughly reviewing the Apache Felix Application Demonstration with shapes. The article state:
When creating an OSGi-based application there are two main orthogonal issues to consider:
- Service model vs. extender model
- Bundled application vs. hosted framework
The first issue is actually a general issue when creating OSGi-based applications. There are two general approaches that can be used when creating an extensible OSGi application. The service model approach uses the OSGi service concept and the service registry as the extensibility mechanism. The extender model approach uses the OSGi installed bundle set as the extensibility mechanism. Both approaches have their advantages and disadvantages and they can be used independently or together.
I think it is a commonly accepted best practice, regarding the second point, to prefer a bundled application, unless for a really good reason you are compelled to use a hosted framework.
Regarding the first point, after having studied both the service model and the extender model I understand the differences between them, but I'm still trying to figure out what are the advantages and disadvantages to the different models.
What are the advantages and disadvantages to each model (Service vs Extender) and what are the best practices for determining which one to use or when it would be appropriate to use a combination of both?
Services are more commonly used and they should normally be your first choice unless you have a compelling reason to design a new extender.
OSGi is a service-oriented platform. A service API forms a contract between two parties, a consumer and a provider. The contract is defined in terms of a Java package containing interfaces, and the provider provides it by implementing those interfaces. The consumer uses the service registry to find instances of an interface it wants to use.
The extender pattern is somewhat more flexible and abstract, but more complicated to understand and use. Essentially, an extender bundle provides additional functionality on behalf of some other bundle(s), which normally opt in by containing some kind of declaration.
For example, suppose you want to implement a Help System for your application. Bundles could simply contain an HTML document under some agreed path, and the central Help System bundle could scan bundles to find these docs and add them to the main Help Index. Doing this with services would be quite cumbersome: assuming you follow the "whiteboard" style you would have to define a HelpProvider
Java interface with a getHelpDocuments()
method; every bundle wishing to provide help would have to implement this interface and register it as a service. On the other hand, the Help System extender bundle needs to be relatively smart because it has to track bundles coming and going. But at least you only have to write this smart code once.
Real-life examples of extenders are as follows:
Service-Component
declaration in other bundles and does all kinds of stuff on their behalf – instantiating components, publishing services etc.Bundle-Blueprint
declaration, or XML files under an agreed path.persistence.xml
file declared by the Meta-Persistence
header. When it finds one it creates a Persistence Unit for that bundle.plugin.xml
file in the root of a bundle.To summarise... services are used for registering and finding objects based on a contract. Extenders are for extending the functionality of bundles, usually based on some kind of declarative resource or header rather than executable code.
The extender model is mainly used for frameworks. It needs to look quite deeply into the bundle impl to do its work. So it is not good for loose coupling. The advantage is that it can define a completely new abstraction like blueprint or declarative services or cdi. All these frameworks use the extender model to wire your bundle based on a spec.
The service model is the right thing for your application itself. Services allow to hide the details of the implementation as well as the instantiation from the user of a service. So this is very good for loose coupling.
In the end both are typically used together. For example you can use cdi annotations to wire your bundle inernally and specify that you offer and consume services. So the cdi framework leverages an extender to wire your bundle internally while you use the service model to loosely connect your bundles.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With