-
Notifications
You must be signed in to change notification settings - Fork 118
3.2. OSGi decoupling
Separating out the API classes from the implementation classes gives much greater flexibility. Having a separate API bundle enables a client to use any implementation provider; additionally, it enables more than one provider to be used simultaneously.
Without this separation, the client bundle would need to be restarted in order to wire to a new provider bundle.
This best practice can also reduce the package dependencies of the API bundle, therefore reducing the possibility of cyclic dependencies between implementations of different APIs. This can easily occur when the two API implementations make use of each others API internally.
From https://www.ibm.com/developerworks/websphere/techjournal/1007_charters/1007_charters.html#sec5
Depending on specifications makes our business code more adaptable to different environments and more robust to future changes. It is not the bundle’s responsibility to determine what concrete implementation to use for its dependencies. This responsibility belongs to the assembly part of the project. It’s in the assembly that we choose the best fitted implementation for the environment where that assembly is going to be deployed. This way we can have multiple assemblies, each deploying the same business code bundle, but providing different implementations for the bundle’s requirements that satisfy the needs for that environment.
For example, one should depend on the JAX-RS specification and not directly on Jersey or Apache CXF.
You may depend on concrete implementations for integration testing purposes. If you are doing unit tests the recommendation is to mock the specification API and not use a concrete implementation dependency. If you do require a specific implementation for integration testing, make sure to set the proper test scope on the maven POM.
Business logic code must not depend, even if only on the specification, on a specific runtime: in this case on OSGi. Those artifacts should be usable both as normal JAR files and as OSGi bundles. OSGi specific classes should never be imported into non-OSGi environment.
As such, business logic code must not import the OSGi specification packages org.osgi.*
and osgi.*
; framework and service platform packages like org.apache.felix.*
; OSGi container packages like org.apache.karaf.*
; and others such as org.ops4j.pax.web.*
and org.apache.cxf.*
.
Using Blueprint is a good practice in general. Some of the benefits that Blueprint provides are support for a simple POJO development and testing model, simple component assembly, and the fact that it is based on open standards.
from https://www.ibm.com/developerworks/websphere/techjournal/1007_charters/1007_charters.html#sec1
Blueprint provides a dependency injection framework which decouples the need of POJOs knowing about the runtime platform.
Activators classes require creating dependencies on OSGi packages. If you really need activators, check if you can separate the bundles between a business logic bundle and an OSGi specific deployment bundle.
If not, only bring OSGi dependencies in activators and mark the dependency as optional. They should be excluded in non-OSGi assemblies.
Use Blueprint descriptors instead of annotations, as annotations also bring in unwanted dependencies.
Logic pertaining the specific OSGi/Karaf runtime (like bundle extenders, deployers, etc.) should be in a separate bundle if they are specific to OSGi.