Child pages
  • OSGi Component / Felix Declarative Service Style Guide
Skip to end of metadata
Go to start of metadata

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:

Component Annontations

Components require the @Component annotation.

  1. Components must declare a name property set to a custom, author-supplied string literal if the component is to be referenced outside the declaring bundle.
    1. Consider using the constant NAME if it is local to the component, or ending in COMPONENT_NAME if defined in another class or constants file.
      1. We used to call these constants PID when we referred to them as "service PIDs" or "config PIDs".  Be sure to replace PID with NAME when working with old code.
    2. The string literal constant should follow the pseudo packaging format "org.forgerock.openidm.someplace.somecomponent" - use human-friendly names for somplace and somecomponent that tries to encapsulate the area of code and purpose of the component.
  2. Components must not declare a name property if the component is not referenced as a service or is only used inside the declaring bundle.
  3. Components must declare a service property if
    1. they are to be registered as a service
    2. they do not implement an interface
    3. they implement multiple interfaces but the author wants control over which interfaces the component is registered

Components must declare @ServiceVendor(ServerConstants.SERVER_VENDOR_NAME) and @ServiceDescription if the component is to be referenced outside the declaring bundle.

Components may omit @ServiceVendor  and @ServiceDescription if the component is only used inside the declaring bundle.

Components must declare @RouterPrefix to provide the handlers route if they implement RequestHandlerSingletonResourceProvider, or @CollectionResourceProvider.

Components must declare @RouterVersion when registering multiple resource versions of RequestHandlerSingletonResourceProvider, or @CollectionResourceProvider handlers.

Reference Annotations

References are the OSGi term for class or object dependencies.  Using SCR, we can include references to indicate dependency injection in a few different ways:

  1. field injection
  2. constructor injection
  3. method injection

Service dependency declarations must be annotated with @Reference.

  1. Use constructor injection when references are unary and static.
  2. Use field injection when references are multiple or dynamic (Hint: Don't use dynamic references at all.)
  3. 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.

Component Declaration Ordering

When writing a component, declare the elements of your class in this order:

  1. static final declarations (loggers, constants, etc)
  2. service dependency field declarations annotated with @Reference
  3. service dependency field declarations requiring bind/unbind methods and the @Reference'd bind/unbind methods themselves should follow immediately after annotated service declarations with these caveats
    1. do not write bind/unbind methods just to perform assignment/unassignment - use constructor injection instead
    2. do write bind/unbind methods when you need to assign the bind method parameter into a different type as the @Reference interface, such as inserting referenced objects with multiple cardinality into a Map
    3. do write bind/unbind methods when you need to perform logic other than or in addition to assignment, such as registering a listener or calling an event notification method which cannot be done in a constructor
  4. final and non-@Reference instance variables
  5. @Activate method or constructor
  6. @Modified method
  7. @Deactivate method
  8. helpers called from activate/modified/deactivate
  9. all other methods (interface implementation(s))
  • No labels