From AEM 6.2, One of our favorite Apache Felix Maven SCR Plugin has been deprecated and in place of this, Maven Bundle Plugin (version 6.2 or greater) has been introduced.
It always take a small effort to adapt new things, But change is the nature’s law. So here we will discuss how OSGi plugin has replaced all SCR annotations in AEM.
Packages:
Now the package “org.apache.felix.scr.annotations.*” will be replaced with “org.osgi.service.component.annotations.*” and “org,osgi.service.metatype.annotations.*”
While using Maven SCR plugin, we can find the Declarative Service(DS) output under /target/classes/OSGi-INF but using OSGi Bundle Plugin our DS output are found in /OSGI-INF, packaged under the compiled JAR File.
How To start with OSGi Annotations?
1.Add a plugin in Parent Pom.xml
<plugin>
<groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>3.2.0</version> <inherited>true</inherited> </plugin> |
2.Add the following maven dependencies.
<dependency>
<groupId>org.osgi</groupId> <artifactId>org.osgi.service.component.annotations</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.annotation</artifactId> <version>6.0.0</version> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.service.metatype.annotations</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.compendium</artifactId> <version>4.2.0</version> <scope>provided</scope> </dependency> |
Note: Make sure that while building the code,plugin is working fine.
Migration of OSGi Components and Service
Before : In SCR Annotations:
@Component(name=”Test Service”,immediate=true,description="this is description")
@Service(TestService.class)
public class TestService {
public String getName()
{
return "testService";
}
}
|
After:In OSGi Annotations
@Component(name=”Test Service” service=TestService.class,immediate=true)
public class TestService {
public String getName()
{
return "testService";
}
}
|
Migration of Servlet
OSGi annotations has reduced our effort to remember a lot of Annotations.
In the Sling Servlets:
We used to use @Component, @Service @SlingServlet @Properties in SCR Annotations.
OSGi annotation just have @Component with the collaboration of all these annotations.
Before : In SCR Annotations:
@SlingServlet(paths="/bin/servlet",selectors = {"test","test1"},extensions = "html")
public class Test extends SlingSafeMethodsServlet{
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)throws IOException
{
response.getWriter().print(" I am in doGet Method");
}
}
|
After:In OSGi Annotations
@Component(service=Servlet.class,
property={
Constants.SERVICE_DESCRIPTION + "=Simple Demo Servlet",
"sling.servlet.methods=" + HttpConstants.METHOD_GET,
"sling.servlet.resourceTypes="+ "com.poc.osgiannotation/components/structure/page",
"sling.servlet.paths="+ "/bin/servlet",
"sling.servlet.extensions=" + "txt"
})
public class SimpleServlet extends SlingSafeMethodsServlet {
{
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)throws IOException
{
response.getWriter().print(" I am in doGet Method");
}
}
|
Custom OSGi Configuration in AEM
OSGi annotations provided a flexibility to create configuration in a separate interface and we can use it in any place.
The OSGi Configurations generates metatype specification that provides a way to describe configuration of the component.Such a metatype information can be used at runtime to generate forms to edit/create the configuration of a component. For example the Apache Felix web console does exactly that.
Let’s understand how to make OSGi configurations in AEM using OSGi Bundle Plugin.
Fig- OSGi COnfiguration in felix Console |
Migration of Custom Workflow Process Step
Before:In SCR Annotations
@Component(immediate = true, enabled = true, metatype = true)
@Service(value = WorkflowProcess.class)
@Property(name = "process.label", value = "Activate Page", propertyPrivate = true)
public class RejectionMailProcess implements WorkflowProcess {
public void execute(WorkItem workitem, WorkflowSession wfsession,MetaDataMap metaDataMap)
{
System,.out.println(“ I am in execute method”);
}
}
|
After: In OSGi Annotations
@Component(service = WorkflowProcess.class, property = {"process.label=Activate Page" })
public class TestWorkflow implements WorkflowProcess {
public void execute(WorkItem workitem, WorkflowSession wfsession,MetaDataMap metaDataMap)
{
System,.out.println(“ I am in execute method”);
}
}
|
How to use @Reference Annotations in OSGi Annotations?
There are multiple ways to use @Reference annotations in OSGi annotations:
1.
2.
@Reference
TestService testService;
|
2.
private TestService testService;
@Reference
public void bindTestService(TestService testService) {
this.testService = testService;
}
public void unbindTestService(TestService testService) {
this.testService = testService;
}
|
If you have any query or suggestion then kindly comment or mail us at sgaem.blog02@gmail.com
Hope it will help you guys !!
Thanks and Happy Learning
Hope it will help you guys !!
Thanks and Happy Learning
Thanks for sharing. More informative comparison between earlier version with new was awesome and straightforward.
ReplyDeleteThanks a lot:) @Michael
DeleteGood one Saurabh
ReplyDeletethanks dear:)
DeleteNicely made. Great article.
ReplyDeletenice post
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteHi,
ReplyDeleteI am glad about this blog spot. These articles are really helpful.
Could you please create an article on using Template Editor as well. I need to learn Template editor and there is no such helpx article. It would be of great help.
Thanks in advance!
Best Regards,
Abhishek
Hi Abhishek,
DeleteYes for sure. We will surely publish blogs on template editor this month.Thanks for the feedback.
Thanks for the helpful guide.
ReplyDeleteUnfortunately I have a problem with using the 1st option of @Reference. The IDE (Eclipse) displays the error message "The annotation @Reference is disallowed for this location" if I don't bind it to a method.
Also I would appreciate it, if you could add a description about how to migrate a replication preprocessor implementation. :)
Hi Andras,
DeleteI was facing the same issues in some of my project, at that time I used the second way to use @Reference annotation,but unfortunately, not able to get the reason.
Hi Shivani,
ReplyDeleteHow to declare filter class with OSGI annotation? Currently we do using SCR annotation as below.
@SlingFilter(order = 100, scope = SlingFilterScope.REQUEST)
Suneel
@Component(service = Filter.class,
Deleteproperty = {
Constants.SERVICE_DESCRIPTION + "=Demo to filter incoming requests",
EngineConstants.SLING_FILTER_SCOPE + "=" + EngineConstants.FILTER_SCOPE_REQUEST,
Constants.SERVICE_RANKING + "=-700"
})
Thanks Shivani.
ReplyDeleteI have created configuration service using OSGI R6 annotations as you mentioned above. Do you know how to inject/reference the configuration service in SlingServlet?
Suneel
Hi Suneel,
DeleteIf you have write OSGi Service like above, you can write it like any other service.
@Reference
UserAccountDetail useraccountDetail;
and call the method.
Hi Shivani, I tried this approach, for some reason it gives me null object. I am using AEM 6.2 version. If I create regular OSGI service (other than config) then @Reference is working. Please let me know what could be wrong here.
DeleteSuneel
Updated the maven dependency for the above issue.
DeleteHi Shivani/Suneel,
DeleteI too have the same issue with @Reference annotation. I am currently using AEM 6.3 version. Both approach 1 and 2 are not working for me. The object referred shows up as null. Do you have any other approach?
Have you checked your maven dependencies????? Put this dependency above all dependencies.
DeleteThis comment has been removed by the author.
ReplyDeleteThank you for your article. But I have one point to your article. I tried to create Workflow Step with new annotation and I found, that for registration new workflow step I need specify service.pid in manual, but old felix plugin specify it automatically. So example of working workflow is:
ReplyDelete@Component(service = WorkflowProcess.class,
property = {
"process.label=MyTrainingWorkflowProcess",
"service.pid=com.aem.samples.core.workflow.MyTrainingWorkflowProcess"
})
public class MyTrainingWorkflowProcess implements WorkflowProcess {
@Override
public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap metaDataMap) throws WorkflowException {
}
}
So, please, fix your example of workflow with new annotation.
I have checked it on AEM 6.2
DeleteWork flow MessageGatewayService(for email notification) using Gateway method throwing null pointer using R6 osgi annotation? Do we have any references for this?
DeleteVery Informative..
ReplyDeleteI created an osgi config as described above and using it in service class but the service pid doesnot show up in bundle. it seems if I make configuration POlicy as optional or if i save my configuration explicitly via configMgr, service PID starts showing up.Do we have to bind or initialize config objects.
ReplyDeleteHi,
ReplyDeleteThanks for your blog. Could you please help with an article on the migration of OSGI run mode configurations from SCR to OSGI R6 anotations.
Excellent. Appreciate you effort!
ReplyDelete@Component
ReplyDelete@Service(value = org.apache.sling.api.adapter.AdapterFactory.class)
@Properties({
@Property(name="service.ranking", intValue = 9999),
@Property(name="adaptables", value={"org.apache.sling.api.resource.Resource"}),
@Property(name="adapters",
value= {"com.cq.services.pagetypes.util.AgcoObject",
"com.cq.services.pagetypes.util.AgcoPage"
})
})
hi, how to migrate multi value property. here adapters is multi value. please help
Hi Abhinash,
DeleteDid you get any solution ?
Regards,
Swati
Yes I found the solution
Delete@Component(service = "org.apache.sling.api.adapter.AdapterFactory.class", property = {
"service.ranking=9999",
"adaptables=org.apache.sling.api.resource.Resource",
"adapters=com.cq.services.pagetypes.util.AgcoObject","adapters=com.cq.services.pagetypes.util.AgcoPage"})
This comment has been removed by the author.
Deletehi,
Deletethen how will we change the annotations for below code :
@Service
@Component(metatype = true, immediate = true, label = "Content Insights Page Name Provider", description = "Service to use custom content insights page name variable")
@Properties({
@Property(name = Constants.SERVICE_DESCRIPTION, value = "Content Insights Page Name Resolver implementation"),
@Property(name = Constants.SERVICE_RANKING, intValue = 200, propertyPrivate = false),
@Property(name = "basePath", value = "/content/myproject/language-masters/en", description="The path to be removed from Content Insights URL", label="basePath"),
@Property(name = "blogBasePath", value = "/content/myproject-blog/en", description="The path to be removed from Content Insights URL for Blogs", label="blogBasePath"),
@Property(name = "cqVarContentInsight", value = "pagedata.path", description="The CQ variable used for Content Insights URL", label="cqVarContentInsight"),
@Property(name = "langBasePath", value = "/content/myproject/language-masters", description="The path to be removed from Content Insights URL", label="langBasePath")})
Nice article.
ReplyDeleteOne thing which puzzles me that with R6 approach, you need to remember a lot more information than SCR annotation.
Secondly as properties are being used to pass key/val pair, you have to remember key value pair for properties. Also editors will not be of much help which was unlike with SCR based annotations.
hi can yo show how the cronexpression ie scheduler.expression property can be defined in the OCD . The scheduler class based on this OCD doesn't get executed (ie the run()method) .
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteHi,
ReplyDeleteCan anyone help me to rewrite the below annotations in AEM 6.4 supported way?
@Component(configurationFactory=true, immediate=true, metatype = true, createPid = false, policy = ConfigurationPolicy.REQUIRE,
name = "IntegrationsServiceConfiguration", label="TestProj: Integration Services Configuration", description="Configuration Factory for all Integration Services")
@Properties({
@Property(name = "service.type", label="Type of Service", description="Select a Service Type",
options = {
@PropertyOption(name = "REST Service", value = "REST Service")
}
),
@Property(name="service.identifier", label="Service Identifier", value="", description="Select a Service Identifier"),
@Property(name="service.url", label="URL", value="", description="Enter the service URL"),
@Property(name="service.authentication", label="Authentication", boolValue =false, description="Does the service requires authentication?"),
@Property(name="service.username", label="Service Username", value="", description="Enter the Username required for authentication"),
@Property(name="service.password", label="Service Password", value="", description="Enter the Password required for authentication"),
@Property(name="service.secured.url", label="Secured URL", boolValue =false, description="Should service connect over the secured https connection"),
@Property(name="service.http.method", label="Http Method", description="Select the Http method to call the Service",
options = {
@PropertyOption(name = "", value = "-- Select One --"),
@PropertyOption(name = "GET", value = "GET"),
@PropertyOption(name = "POST", value = "POST"),
@PropertyOption(name = "PUT", value = "PUT"),
@PropertyOption(name = "DELETE", value = "DELETE")
}
),
@Property(name="service.params", label="Additional Configuration Params", cardinality = 25,value ="" ,description="Add one key:value pair per line with \":\" as delimiter"),
@Property(name="service.xapikey", label="x-api-key", value="", description="Enter the x-api-key"),
})
Thanks,
Abhinav.
Hi Abhi,
DeleteDid you get the solution for this? If so what's that?
Hi Vijay,
DeleteI didn't get the solution yet.
Thanks,
Abhinav.
Hi abhi,
DeleteDid you get any solution because I am also facing the same issue ?
Regards,
Swati
This comment has been removed by the author.
ReplyDeleteGood article..Thanks
ReplyDeleteI am getting this error "annotation type not applicable to this kind of declaration
ReplyDelete"
when I try @Reference
TestService testService; instead of usea method, any help?, please
Nice one.
ReplyDeleteHow to convert OSGi service factory from scr annotations
ReplyDeleteNice Blog. Thanks for sharing it with us. Migration Agents in Brisbane
ReplyDeleteMua vé máy bay tại đại lý Aivivu, tham khảo
ReplyDeletesăn vé máy bay giá rẻ đi Mỹ
có vé máy bay từ mỹ về việt nam không
mua ve may bay gia re tu duc ve viet nam
chuyến bay từ nga về việt nam