8 Replies Latest reply on Oct 3, 2018 9:16 AM by chakravarthysvsn

    AEM 6.3 || How to call OSGi Service in Sling Model with Service wrote by OSGi R6 Annotation

    tinyt6510512 Level 1

      Dear AEM Community,

       

       

      Currently, I'm working on AEM 6.3 OSGi R6 Official OSGi Declarative Services Annotations in AEM - Adobe Experience Manager | AEM/CQ | Apache Sling

      But we can't call it in Sling model, we can't use annotation @Reference (import org.osgi.service.component.annotations.Reference) or @Inject ( from Sling Model) or @Inject @Source("osgi-services").

       

      Any help would be greatly appreciated.

       

      Thanks,

      Thomas.

       

        • 1. Re: AEM 6.3 || How to call OSGi Service in Sling Model with Service wrote by OSGi R6 Annotation
          Feike Visser Adobe Employee

          Normally @Inject must always work.

           

          Can you share a bit more code?

          • 2. Re: AEM 6.3 || How to call OSGi Service in Sling Model with Service wrote by OSGi R6 Annotation
            tinyt6510512 Level 1

            Hi Feike,

             

            Thanks for your support.

             

            Here is the source code

            OSGi Services with OSGi R6 Annotation.

             

            import org.apache.commons.lang3.StringUtils;

            import org.apache.sling.api.resource.ValueMap;

            import org.osgi.service.component.annotations.Component;

            import org.osgi.service.component.annotations.Reference;

            import org.slf4j.Logger;

            import org.slf4j.LoggerFactory;

             

            @Component(service={ProductSearchService.class}, immediate=true)

            public class ProductSearchServiceImpl

              implements ProductSearchService {

            // omitted

            }

             

            I checked on the OSGi bundle, the services has a status active

            Sling Model Class

            import javax.annotation.PostConstruct;

            import javax.inject.Inject;

            import org.apache.sling.api.SlingHttpServletRequest;

            import org.apache.sling.api.SlingHttpServletResponse;

            import org.apache.sling.api.resource.Resource;

            import org.apache.sling.api.resource.ValueMap;

            import org.apache.sling.models.annotations.DefaultInjectionStrategy;

            import org.apache.sling.models.annotations.Model;

            import org.apache.sling.models.annotations.injectorspecific.SlingObject;

            import org.slf4j.Logger;

            import org.slf4j.LoggerFactory;

             

            @Model(adaptables={SlingHttpServletRequest.class}, defaultInjectionStrategy=DefaultInjectionStrategy.OPTIONAL)

            public class ModelList

            {

              private static final Logger LOGGER = LoggerFactory.getLogger(ModelList.class);

              private List<Map<String, Object>> listProperties;

              private List<Integer> pageList;

              private Paging paging;

              @Inject

              protected ProductSearchService searchService;

             

            @PostConstruct

              protected void postInit()

              {

                Resource resource = this.request.getResource();

                ValueMap properties = resource.getValueMap();

             

                // omited

               result = this.searchService.getListFromParent(resource);

             

              

            }

             

            It's a null when we debugged at this.searchService

             

             

            Thanks,

            Thomas.

            • 3. Re: AEM 6.3 || How to call OSGi Service in Sling Model with Service wrote by OSGi R6 Annotation
              smacdonald2008 Adobe Employee

              @Reference does not work in HTL Java classes like Sling Models or WCMUsePojo.

               

              We talk about this in the AEM TIP section: Scott's Digital Community: Adobe Experience Manager FAQs and other Tips

               

              CAN I USE @REFERENCE IN AN HTL CLASS THAT EXTENDS WCMUSEPOJO

              You cannot use the @Reference annotation from a HTL class that extends WCMUsePojo. This can be used from a Java class that uses @Service to reference another service known as dependency injection. To learn about Dependency Injection in AEM, see this article:

               

              Injecting a DataSourcePool Service into an Adobe Experience Manager OSGi bundle

               

              Now to learn how to get a referenece to another AEM service from a class that extends WCMUsePojo, see this article:

               

              Creating an AEM HTL component that queries the JCRhttps://helpx.adobe.com/experience-manager/using/htl_jcr.html

               

              Notice we have this code:

               

              //Use getSlingScriptHelper().getService() to get an instance of the CustomerService

                      custService = getSlingScriptHelper().getService(CustomerService.class);

              • 4. Re: AEM 6.3 || How to call OSGi Service in Sling Model with Service wrote by OSGi R6 Annotation
                smacdonald2008 Adobe Employee

                Having said that - i have only used this from WCMUsePojo - I have not tried on Sling Model. I will try that and post back.

                • 5. Re: AEM 6.3 || How to call OSGi Service in Sling Model with Service wrote by OSGi R6 Annotation
                  smacdonald2008 Adobe Employee

                  THe getSlingScriptHelper().getService();

                   

                  only works from WCMUsePojo.

                   

                  I just tested using @inject and it works to inject a running AEM Service into a Sling Model .

                   

                  Given these classes:

                   

                  ASlingRef1.png

                   

                   

                  KeyService interface:

                   

                  package com.community.aem.core;

                   

                  public interface KeyService {

                   

                      public void setKey(int val);

                      public String getKey();

                   

                  }

                   

                  KeyServiceImpl class

                   

                  package com.community.aem.core;

                   

                  import org.apache.felix.scr.annotations.Component;

                  import org.apache.felix.scr.annotations.Service;

                   

                   

                  //This is a component so it can provide or consume services

                  @Component

                   

                  @Service

                  public class KeyServiceImpl implements KeyService {

                   

                    

                      //Define a class member named key

                      private int key = 0 ;

                    

                      @Override

                      //A basic setter method that sets key

                      public void setKey(int val)

                      {

                          //Set the key class member

                          this.key = val ;

                         

                      }

                   

                      @Override

                      //A basic getter that gets key

                      public String getKey()

                      {

                          //return the value of the key class member

                         

                          //Convert the int to a String to display it within an AEM web page

                          String strI = Integer.toString(this.key);

                          return strI;

                      }

                  }

                  .

                   

                  We can inject KeyService into HelloWorldModel - see:

                   

                  package com.community.aem.core.models;

                   

                  import javax.annotation.PostConstruct;

                  import javax.inject.Inject;

                  import javax.inject.Named;

                   

                  import com.community.aem.core.KeyService;

                   

                  import org.apache.sling.api.resource.Resource;

                  import org.apache.sling.models.annotations.Default;

                  import org.apache.sling.models.annotations.Model;

                  import org.apache.sling.settings.SlingSettingsService;

                   

                  @Model(adaptables=Resource.class)

                  public class HelloWorldModel {

                   

                      @Inject

                      private KeyService keyService;

                   

                      @Inject

                      private SlingSettingsService settings;

                   

                      @Inject @Named("sling:resourceType") @Default(values="No resourceType")

                      protected String resourceType;

                   

                      private String message;

                   

                      @PostConstruct

                      protected void init() {

                       

                         

                          keyService.setKey(80) ;

                       

                          message = "\tHello World! - the keyservice is " +keyService.getKey() +" \n";

                          message += "\tThis is instance: " + settings.getSlingId() + "\n";

                          message += "\tResource type is: " + resourceType + "\n";

                      }

                   

                      public String getMessage() {

                          return message;

                      }

                  }

                   

                   

                  This works -- you can see the successful output here. I hope this clears up how to reference a running AEM Service from WCMUsePojo and Sling models.

                   

                   

                  ASLingREF.png

                   

                   

                   

                  You can try this too by following this article to get the default class:

                   

                  Creating an Adobe Experience Manager 6.3 Project using Adobe Maven Archetype 11

                   

                   

                  Then add the KeyService and Impl class to the com.community.aem.core package. You will get the same result.  BE  sure to add the new code (bolded code above) to the Sling Model class too!

                  2 people found this helpful
                  • 6. Re: AEM 6.3 || How to call OSGi Service in Sling Model with Service wrote by OSGi R6 Annotation
                    tinyt6510512 Level 1

                    Hi smacdonald2008, Feike,

                     

                    Thanks for your support. After i removed and refresh the bundle it's worked with @Inject annotation.

                     

                    Thanks,

                    Thomas.

                    • 7. Re: AEM 6.3 || How to call OSGi Service in Sling Model with Service wrote by OSGi R6 Annotation
                      smacdonald2008 Adobe Employee

                      I am glad that its working for you. I also added this to our AEM tip blog.

                      • 8. Re: AEM 6.3 || How to call OSGi Service in Sling Model with Service wrote by OSGi R6 Annotation
                        chakravarthysvsn Level 1

                        if i don't define the interface can't we inject the services.

                         

                        As one of my service don't have any interface . initially it is not working and only working when i added a interface to it.

                        But it is existing code, i should not change that code