|Table of Contents|
When writing an OSGi component, additional annotations, declarations, and methods are used to facilitate the OSGi lifecycle. Keeping this in a consistent order helps people find the parts they need to work on. Please adhere to these guidelines:
Components require the
- Use constructor injection when references are unary and static.
- Use field injection when references are multiple or dynamic (Hint: Don't use dynamic references at all.)
- Use bind methods and method injection any time when you need to transform (add business logic) to the event of a reference becoming available to the component.
Notes on ReferencePolicy.DYNAMIC
Dynamic references must be
This is enforced by the
maven-bundle-plugin. The rationale is this: The DYNAMIC ReferencePolicy indicates that the reference can be dynamically be set by the OSGi Framework at runtime. This means that, for memory visibility at the site of usage of the referenced field, that field must be
volatile to guarantee visibility to changes across threads. Even if your code is not multi-threaded, there is high likelihood that the OSGi Framework is and that it may update your field's reference in a different thread than your code is executing.
Dynamic, mandatory, unary references are a lie.
This is the "
ReferencePolicy.DYNAMIC is a lie" rule. Earlier versions of IDM development did not properly understand the meaning of a dynamic reference policy. As stated above, this means that the OSGi Framework can dynamically set the value of the reference when a new one is available. Early development took that to mean that, as a dependency was updated or changed, your component could have its reference on that dependency swapped out at runtime without deactivating the component. This is partially true. The missing ingredient in previous thinking was that reference cardinality trumps reference policy. The default cardinality of a reference is
ReferenceCardinality.MANDATORY, or 1:1, which means that the component must have at least one and only one reference to the referenced component. If there are zero references available to satisfy the dependency, your component will not be activated (or will deactivate if the reference is marked to go away). So adding
ReferencePolicy.DYNAMIC to a mandatory, unary reference is a lie. It will not be treated as dynamic at all. The proper way to use dynamic references are with
ReferenceCardinality.MULTIPLE references. Do not add
ReferencePolicy.DYNAMIC to unary references.
Component Declaration Ordering