{"id":5203,"date":"2018-09-26T12:08:36","date_gmt":"2018-09-26T06:38:36","guid":{"rendered":"\/?p=5203"},"modified":"2020-08-17T11:44:49","modified_gmt":"2020-08-17T06:14:49","slug":"migration-of-scr-annotations-to-ds-annotations","status":"publish","type":"post","link":"https:\/\/www.argildx.us\/technology\/migration-of-scr-annotations-to-ds-annotations\/","title":{"rendered":"How to Migrate from SCR Annotations to DS Annotations"},"content":{"rendered":"
Change is a rule of life, and if you are not updating yourself on current trends then you are constantly falling behind on new updates that can be essential to your system. With Adobe, they release a new version of AEM every year. Last year, they introduced SCR annotations, and now they are supporting DS annotations. From AEM 6.2 <\/span>DS Annotations<\/b> are supported,<\/span> and it is highly recommended that you use these in the newer version of AEM. This is why you need to learn how to migrate from SCR Annotations to DS Annotations.<\/span><\/p>\n Let’s look at brief introductions of SCR Annotations and DS Annotations. <\/span><\/p>\n SCR stands for Service Component Runtime. The \u201dmaven-scr-plugin\u201d uses scr annotations from the corresponding subproject at Apache Felix. All annotations are in \u201corg.apache.felix.scr.annotations\u201d package. The Apache Felix SCR described by the OSGi Declarative Services Specification is implemented by the \u201corg.apache.felix.scr\u201d bundle. <\/span><\/p>\n SCR annotations do not support new feature from R6 and above. It is highly recommended to use OSGi annotations for Declarative Services instead. <\/span><\/p>\n DS annotation is an official implementation from OSGi R6 (release 6) specification. It is also known as <\/span>OSGi Declarative Services Annotations. For DS annotations we have to use <\/span>“maven-bundle-plugin”<\/b> instead of “maven-scr-plugin”. <\/span>Version 3.2.0 or greater. For DS annotations we need artifacts “<\/span>org.osgi.service.metatype.annotations<\/b>” <\/span>and <\/span>“<\/span>org.osgi.service.component.annotations<\/b>” instead <\/span>“<\/b>org.osgi.core” and “org.osgi.compendium”. <\/span><\/p>\n In DS Annotation, package \u201corg.apache.felix.scr.annotations.*\u201d will be replaced with <\/span>\u201corg.osgi.service.component.annotations.*\u201d<\/b> and <\/span>\u201corg,osgi.service.metatype.annotations.*\u201d<\/b>. <\/span><\/p>\n Migration of Component and Services: We used to use @Component, @Service @SlingServlet @Properties in SCR Annotations while DS annotation just has @Component with the collaboration of all these annotations. <\/span><\/p>\n Major changes came in custom OSGi configuration. OSGi annotations provided a flexibility to create configuration in a separate interface and we can use it in any place. <\/span><\/p>\n <\/p>\n Migration of OSGi config is quite tricky. There are two scenarios for OSGi config. <\/span><\/p>\n Change is a rule of life, and if you are not updating yourself on current trends then you are constantly falling behind on new updates that can be essential to your system. With Adobe, they release a new version of AEM every year. Last year, they introduced SCR annotations, and now they are supporting DS … Read more<\/a><\/p>\n","protected":false},"author":29,"featured_media":6658,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","content-type":"","footnotes":""},"categories":[66],"tags":[1757,1763,99,1764],"yst_prominent_words":[1068,1060,1762,1760,1062,1066,1067,1058,1059,1056,1562,1761,1061,1559,1063,1064,1057,1065,1759,1758],"acf":[],"yoast_head":"\nWhat are SCR Annotations?<\/b><\/h5>\n
What are DS Annotations?<\/b><\/h5>\n
\n<\/b><\/b>Remember that declarative services are a compiled time process. For DS annotations to be effective, they must be handled during the build process.
\n<\/span>The migration from SCR annotations to DS annotations is fairly easy and both annotation styles will work side-by-side while you complete the switch-over.
\n<\/span>So here will we discuss how to migrate from SCR annotations to DS annotations. <\/span><\/p>\nPlugin:<\/b><\/h5>\n
\n<\/span><\/p>\n<plugin>\n\n<groupId>org.apache.felix<\/groupId>\n\n<artifactId>maven-bundle-plugin<\/artifactId>\n\n<version>3.5.1<\/version>\n\n<inherited>true<\/inherited>\n\n<\/plugin>\n\n<\/pre>\n
\nDependencies:<\/b><\/h5>\n<dependency>\n\n<groupId>org.osgi<\/groupId>\n\n<artifactId>org.osgi.service.component.annotations<\/artifactId>\n\n<version>1.3.0<\/version>\n\n<scope>provided<\/scope>\n\n<\/dependency>\n\n\n<dependency>\n\n<groupId>org.osgi<\/groupId>\n\n<artifactId>org.osgi.service.metatype.annotations<\/artifactId>\n\n<version>1.3.0<\/version>\n\n<\/dependency>\n\n<\/pre>\n
Java Package:<\/b><\/h5>\n
\n<\/b>We used to use @Component, @Service annotations in SCR Annotations while in DS annotation just have @Component annotation with the collaboration of all these annotations. <\/span><\/p>\nSCR annotation Implementation:<\/b><\/h5>\n
@Component(label = \"Demo Service\", immediate = true)\n@Service(DemoService.class)\n\npublic class DemoService {\n public String getMyClassName() {\n return \"DemoService\";\n }\n}<\/pre>\n
\nDS annotation Implementation:<\/b><\/h5>\n@Component(name = \"Demo Service\", immediate = true, service = DemoService.class)\n\npublic class DemoService {\n public String getMyClassName() {\n return \"DemoService\";\n }\n}<\/pre>\n
Migration of Sling Servlet:<\/b><\/h5>\n
SCR annotation Implementation<\/b><\/h5>\n
@SlingServlet( resourceTypes = \"sling\/servlet\/default\",\n methods = {\"POST\", \"GET\"},\n selectors = \"demoServlet\",\n extensions = \"fetch\")\n\npublic class Demo extends SlingSafeMethodsServlet {\n @Override\n protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException { \n response.getWriter().print(\"doGet Method\"); }\n\n @Override\n protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException { \n response.getWriter().print(\"doPost Method\");\n }\n}<\/pre>\n
\nDS annotation Implementation:<\/b><\/h5>\n@Component(service = Servlet.class,\n property = {\n \"sling.servlet.methods=\" + HttpConstants.METHOD_GET,\n \"sling.servlet.methods=\" + HttpConstants.METHOD_POST,\n \"sling.servlet.resourceTypes=\" + \"sling\/servlet\/default\",\n \"sling.servlet.selectors=\" + \"demoServlet\",\n \"sling.servlet.extensions=\" + \"fetch\"})\n\npublic class Demo extends SlingSafeMethodsServlet {\n @Override\n protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {\n response.getWriter().print(\"doGet Method\");\n }\n\n @Override\n protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {\n response.getWriter().print(\"doPost Method\");\n }\n}<\/pre>\n
\nMigration of Custom Workflow process:
\n<\/b>SCR annotations Implementation:<\/b><\/h5>\n@Component(immediate = true, enabled = true, metatype = true)\n@Service(value = WorkflowProcess.class)\n@Property(name = \"process.label\", value = \"Demo Process\", propertyPrivate = true)\n\npublic class DemoProcess implements WorkflowProcess {\n public void execute(WorkItem workitem, WorkflowSession wfsession, MetaDataMap metaDataMap) {\n System.out.println(\"I am in execute method\");\n }\n}<\/pre>\n
\nDS annotation Implementation:<\/b> <\/span><\/h5>\n@Component(service = WorkflowProcess.class, \n immediate = true, enabled = true,\n property = {\"process.label= Demo Process\"})\n\npublic class DemoProcess implements WorkflowProcess {\n public void execute(WorkItem workitem, WorkflowSession wfsession, MetaDataMap metaDataMap) {\n System.out.println(\u201c I am in execute method\u201d);\n }\n}<\/pre>\n
\nMigration of Custom OSGi Configuration:<\/b><\/h5>\nSCR annotations Implementation:<\/b><\/h5>\n
@Component(immediate = true, metatype = true, label = \"Customer Configuration\")\n@Service(value = CustomerDemo.class)\n\npublic class CustomerDemo {\n @Property(label = \"Custmer Name\", value = \"default value\")\n private static final String CUST_NAME = \"custmer.name\";\n \n @Property(label = \"Custmer address\", value = \"default value\")\n private static final String CUST_ADDR = \"custmer.address\";\n private String custmerName; \n private String custmerAddr;\n\n @Activate\n protected void activate(Map context) {\n custmerName = PropertiesUtil.toString(context.get(CUST_NAME), EMPTY);\n custmerAddr = PropertiesUtil.toString(context.get(CUST_ADDR), EMPTY);\n } \n\n @Modified\n protected void modified(ComponentContext context) {\n custmerName = PropertiesUtil.toString(context.getProperties().get(CUST_NAME), EMPTY);\n custmerAddr = PropertiesUtil.toString(context.getProperties().get(CUST_ADDR), EMPTY);\n\n }<\/pre>\n
\nDS annotation Implementation:
\n<\/b>Interface:<\/b><\/h5>\nimport org.osgi.service.metatype.annotations.ObjectClassDefinition;\n@ObjectClassDefinition(name = \"Customer Configuration\")\n\npublic @interface CustomerConfig {\n @AttributeDefinition(name = \"Custmer Name\")\n String CUST_NAME() default \"default value\";\n @AttributeDefinition(name = \"Custmer address\")\n String CUST_ADDR() default \"default value\";\n}<\/pre>\n
\nActual Class:<\/b><\/h5>\nimport org.osgi.service.component.annotations.Activate;\n import org.osgi.service.component.annotations.Component;\n import org.osgi.service.component.annotations.Modified;\n import org.osgi.service.metatype.annotations.Designate;\n\n@Component(service = CustomerDemo.class, immediate = true)\n@Designate(ocd = CustomerConfig.class)\n\npublic class CustomerDemo { \n private String custmerName;\n\n private String custmerAddress;\n @Activate\n @Modified\n protected void Activate(final CustomerConfig custmerconfig) {\n custmerName = custmerconfig.CUST_NAME();\n custmerAddress = custmerconfig.CUST_ADDR();\n }\n}<\/pre>\n
\nFig- OSGi Configuration in Felix Console<\/b><\/h5>\n
\nMigration of OSGi Config:<\/b><\/h5>\n\n
Scenario 1:<\/b>
\n<\/span>If you have created your own custom config. For e.g. <\/span><\/h5>\nInterface:
\n<\/b><\/h6>\nimport org.osgi.service.metatype.annotations.ObjectClassDefinition;\n@ObjectClassDefinition(name = \"Demo Configuration\")\n\npublic @interface Demo {\n @AttributeDefinition(name = \"My Name\")\n String myName() default \"Abc\";\n @AttributeDefinition(name = \"Address\")\n String myAddress() default \"default address\";\n}<\/pre>\n
So, your default configuration will be:<\/b><\/h6>\n
<? xml version = \"1.0\" encoding=\"UTF-8\"?>\n<jcr:root xmlns:sling=\"http:\/\/sling.apache.org\/jcr\/sling\/1.0\"xmlns:jcr=\"http:\/\/www.jcp.org\/jcr\/1.0\"\n jcr:primaryType=\"sling:OsgiConfig\"\n myName=\"XYZ\"\n myAddress=\"default address\"\/><\/pre>\n
\nScenario 2:
\n<\/b>If you have already default configuration and you are migrating to DS annotation. For e.g. <\/span><\/h5>\nConfig file:<\/b><\/h6>\n
<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n<jcr:root xmlns:sling=\"http:\/\/sling.apache.org\/jcr\/sling\/1.0\" xmlns:jcr=\"http:\/\/www.jcp.org\/jcr\/1.0\" \n jcr:primaryType=\"sling:OsgiConfig\" \n smtp.host=\"smtp.office365.com\" \n smtp.passsword=\"{474c6b96ab4d}\" \n smtp.port=\"587\" \n smtp.user=\"noreply.onmicrosoft.com\"\/> \n\n<\/pre>\n
\nSo, your interface will be:<\/b><\/h6>\nimport org.osgi.service.metatype.annotations.ObjectClassDefinition;\nimport org.osgi.service.metatype.annotations.AttributeDefinition;\n\n@ObjectClassDefinition(name = \"Email Configuration\")\npublic @interface EmailConfig {\n @AttributeDefinition(name = \"SMTP server host name\")\n String smtp_host();\n\n @AttributeDefinition(name = \"SMTP server port\")\n String smtp_port();\n\n @AttributeDefinition(name = \"SMTP user\")\n String smtp_user();\n\n @AttributeDefinition(name = \"SMTP password\")\n String smtp_passsword();\n}<\/pre>\n
\nHope this article helped you learn and carry out the implementation and workflow to migrate from SCR annotations to DS annotations. <\/span><\/p>\n","protected":false},"excerpt":{"rendered":"