By now you're pretty comfortable writing OSGi components and services using the Felix SCR annotations. However, with AEM 6.2 and greater comes support for the official OSGi Declarative Services annotations. This is exciting for two reasons. First, it's the official implementation; and second, it provides access to future improvements and specification advancements. The Felix Maven SCR plugin probably won't be providing much in the way of future enhancements. In fact, taken directly from the from the
Apache Felix Maven SCR Plugin website:
"While the Apache Felix Maven SCR Plugin is a great tool for developing OSGi components using Declarative Services you should use the official annotations from the OSGi R6 specification. The development of the Apache Felix SCR Plugin is in maintenance mode."
The
Apache Sling project and the
Adobe Experience Manager product are both moving in this direction and it's suggested that you consider it for your project as well. The migration is fairly easy and both annotation styles will work side-by-side while you complete the switch-over.
Declarative Services
Remember that declarative services is a compile time process. In order for the DS annotations to be effective, they must be handled during the build process. The Apache Felix SCR annotations require the
maven-scr-plugin
while the OSGi DS annotations require the
maven-bundle-plugin
version 3.2.0 or greater.
With the
maven-scr-plugin
you may be used to finding the DS output under
/target/classes/OSGI-INF
and
/target/classes/OSGI-INF/metatype
. With the
maven-bundle-plugin
you will have to unzip the compiled artifact (the jar file) to find the DS output in its
/OSG-INF
directory.
Java Packages
Rather than using
org.apache.felix.scr.annotations.*
, you'll use
org.osgi.service.component.annotations.*
and
org.osgi.service.metatype.annotations.*
.
Dependencies
Rather than using the
maven-scr-plugin
, you need the
maven-bundle-plugin
version 3.2.0 or greater.
You also need the artifacts
org.osgi.service.metatype.annotations
and
org.osgi.service.component.annotations
(currently version 1.3.0) rather than
org.osgi.core
and
org.osgi.compendium
. See the provided sample project's POM file for more specifics.
Once you update your project's dependencies, you'll find that your IDE will inform you that the
org.apache.felix.scr.annotations.*
annotations are deprecated.
Service Configuration
The most noticeable difference between Felix SCR annotations and OSGi DS annotations is where service reference properties are defined. With Felix annotations everything is in the Properties and Property annotations either at the head of the class file or inline. OSGi DS annotations move the service reference properties to it's own class.
The annotations will move to their own class which declutters the component or service. For components with a large amount of options, you might find that you like an independent class, while a component with only one or two properties may be fine as a subclass.
Service Reference Properties
The
AttributeDefinition
method naming convention will immediately seem out of place. It's very
Pythonic looking with its use of underscores. You don't need to write your method names that way, but the reason for doing so is that the underscores are converted to dots for display in the Felix console and your OSGi configs. For example, you're probably familiar with seeing properties defined as something like
resource.resolver.searchpath
. To achieve this in your configuration class, your method would be named
resource_resolver_searchpath
.
Provided is an example of how to create each individual property type with the newer OSGi annotations:
SlingServlet Annotation
The
SlingServlet
annotation is a special case - it's a convenience annotation and unfortunately it's not available anymore. However, the idea is that it will be available in the future as a custom annotation provided by Sling working in the OSGi DS framework when R7 is released. Your current SCR SlingServlet looks something like this (although without all the available properties set):
Instead, use a regular component annotation with service type
Servlet.class
. The service reference properties for paths, extensions, selectors, methods and resourceTypes are simple String properties. When setting array properties, set each entry on a new line. See the Apache Sling docs on
Servlet Registration for the available service reference properties. When setting a non-String property value such as an Integer or Boolean, include the type such as
service.ranking:Integer=100
. Here's the OSGi version of that same servlet (again, you probably won't use all the available properties in your servlet):
Expanded Examples
Further Reading
Adobe Marketing Cloud: