Expand my Community achievements bar.

Join us in celebrating the outstanding achievement of our AEM Community Member of the Year!
SOLVED

Can not use OSGi Service in WCMUsePojo class

Avatar

Level 1

I want to read OSGI run mode configurations with OSGI R6 annotation (the code above).

I found the error in the log file and the applicationConfiguration variable in ComponentApi class always have null value.

Any wrong in my code?

1 Accepted Solution

Avatar

Correct answer by
Level 10

Hi,

I tried to execute your code in my local (in your original post) and I was able to reproduce your issue of service Object being null.

When I changed the service name in my Impl Class, it works. Adding the complete snippet for your reference.

(in Pojo class, I added a getter for addressApi for testing the value entered via OSGI config)

AppConfig.Java

@ObjectClassDefinition(name = "Sprint2AEM - Application Configuration", description = "This contains all application configuration")

public @interface AppConfig {

@AttributeDefinition(name = "address.api",description = "Domain",type = AttributeType.STRING)

String getAddressApi() default "";

}

ApplicationConfiguration.java:

public interface ApplicationConfiguration {

     public String getAddressApi();

}

ApplicationConfigurationImpl.java:

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

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

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

import org.osgi.service.metatype.annotations.Designate;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

@Component(service = ApplicationConfiguration.class,immediate = true)

@Designate(ocd = AppConfig.class)

public class ApplicationConfigurationImpl implements ApplicationConfiguration{

     private static final Logger LOG = LoggerFactory.getLogger(ApplicationConfigurationImpl.class);

     private String addressApi;

  @Activate

  @Modified

   private void activate(AppConfig appConfig){

      this.addressApi = appConfig.getAddressApi();

   }

     @Override

   public String getAddressApi() {

      return addressApi;

   }

}

ComponentApi.java(Extending WCMUsePojo)

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.adobe.cq.sightly.WCMUsePojo;

public class ComponentApi extends WCMUsePojo{

     private static final Logger LOG = LoggerFactory.getLogger(ComponentApi.class);

     private String apiUrl="";

     private String addressApi;

@Override

public void activate() throws Exception {

         ApplicationConfiguration applicationConfiguration = getSlingScriptHelper().getService(ApplicationConfiguration.class);

         LOG.info("App configuration Service Object Test=="+applicationConfiguration);

         addressApi = applicationConfiguration.getAddressApi();

        //apiUrl = addressApi + get("apiUrl", String.class);

}

public String getAddressApi() { return addressApi; }

public String getApiUrl() { return apiUrl; }

}

HTL Code:

<h3>Hello World component - Testing OSGI config and Service reference from WCMUsePojo</h3>

<div data-sly-use.obj="com.aem.learnings.core.ComponentApi">

${obj.addressApi ? obj.addressApi : "Not from pojo/OSGI Config"}      

</div>

Screenshots:

OSGiConfig.png

OSGI Page.png

View solution in original post

14 Replies

Avatar

Employee

Code seems ok, please have a look in the bundle is started, and the service is active in the OSGi console (/system/console)

Avatar

Level 10

Here is the WCMUsePojo syntax to get a refernece to an AEM Service:

public void activate() {

        this.numberOfMovies = Integer.valueOf(getProperties().get("maxMovies", ""));

        this.path = getProperties().get("moviesPath", "");

        

        service = getSlingScriptHelper().getService(MovieInterface.class);

    }

You can see this in this HELPX article -- Adobe Experience Manager Help | Creating an AEM 6.3 HTML Template Language movie component

This Article uses DS annotations. Official OSGi Declarative Services Annotations in AEM - Adobe Experience Manager | AEM/CQ | Apache S...

Avatar

Level 10

HI,

Service property in @Component annotation has impl class. Can you change it to "ApplicationConfiguration.class"

@Component(service = ApplicationConfigurationImpl.class,immediate = true)

@Designate(ocd = AppConfig.class)

public class ApplicationConfigurationImpl implements ApplicationConfiguration{

....

Avatar

Level 1

Thanks for response.

But in my example: getSlingScriptHelper().getService(ApplicationConfiguration.class) return null. So I can not call methods from this service.

Avatar

Level 1

Hi, @vijis31358935.

​I tried your solution but still not working.

Avatar

Level 10

Try writing a test service and ude @Reference. See if that returns a reference to your service. I am thinking it too may return null. This will tell us if there is an issue with your service.

Avatar

Level 1

@Override
public void activate() throws Exception {

   ConfigurationAdmin confAdmin = getSlingScriptHelper().getService(ConfigurationAdmin.class);
   Configuration conf = confAdmin.getConfiguration("com.aem.sprint2.core.core.configuration.impl.ApplicationConfigurationImpl");
   Dictionary<String, Object> props = conf.getProperties();

   addressApi = props.get("getAddressApi").toString();

   apiUrl = addressApi + get("apiUrl", String.class);

}

I found this way can get properties OSGI configuration.

Please give me the opinion of this way?

Avatar

Level 1

I've tried using @Reference before, but it return null.

Following this discussion how to read OSGI configuration via JAVA , the correct answer is

So I'm trying finding another ways.

Avatar

Level 10

Have you tested your service using another method other then WCMUsePojo.

When I said use @Reference, i meant setup a test service that uses @Component in the Java class -- not from the WCMUSePojo class.

I suspect your issue is the service is not valid. That is why i asked you to invoke it outside of WCMUsePojo.  Be sure that its a valid service and you can use dependency injection successfully from within another AEM Service.

Avatar

Correct answer by
Level 10

Hi,

I tried to execute your code in my local (in your original post) and I was able to reproduce your issue of service Object being null.

When I changed the service name in my Impl Class, it works. Adding the complete snippet for your reference.

(in Pojo class, I added a getter for addressApi for testing the value entered via OSGI config)

AppConfig.Java

@ObjectClassDefinition(name = "Sprint2AEM - Application Configuration", description = "This contains all application configuration")

public @interface AppConfig {

@AttributeDefinition(name = "address.api",description = "Domain",type = AttributeType.STRING)

String getAddressApi() default "";

}

ApplicationConfiguration.java:

public interface ApplicationConfiguration {

     public String getAddressApi();

}

ApplicationConfigurationImpl.java:

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

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

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

import org.osgi.service.metatype.annotations.Designate;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

@Component(service = ApplicationConfiguration.class,immediate = true)

@Designate(ocd = AppConfig.class)

public class ApplicationConfigurationImpl implements ApplicationConfiguration{

     private static final Logger LOG = LoggerFactory.getLogger(ApplicationConfigurationImpl.class);

     private String addressApi;

  @Activate

  @Modified

   private void activate(AppConfig appConfig){

      this.addressApi = appConfig.getAddressApi();

   }

     @Override

   public String getAddressApi() {

      return addressApi;

   }

}

ComponentApi.java(Extending WCMUsePojo)

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.adobe.cq.sightly.WCMUsePojo;

public class ComponentApi extends WCMUsePojo{

     private static final Logger LOG = LoggerFactory.getLogger(ComponentApi.class);

     private String apiUrl="";

     private String addressApi;

@Override

public void activate() throws Exception {

         ApplicationConfiguration applicationConfiguration = getSlingScriptHelper().getService(ApplicationConfiguration.class);

         LOG.info("App configuration Service Object Test=="+applicationConfiguration);

         addressApi = applicationConfiguration.getAddressApi();

        //apiUrl = addressApi + get("apiUrl", String.class);

}

public String getAddressApi() { return addressApi; }

public String getApiUrl() { return apiUrl; }

}

HTL Code:

<h3>Hello World component - Testing OSGI config and Service reference from WCMUsePojo</h3>

<div data-sly-use.obj="com.aem.learnings.core.ComponentApi">

${obj.addressApi ? obj.addressApi : "Not from pojo/OSGI Config"}      

</div>

Screenshots:

OSGiConfig.png

OSGI Page.png

Avatar

Level 10

Great response - we marked that as correct!

Avatar

Level 1

Thanks all for response.

Following the code of @

Avatar

Level 7

we can not make a WCMuse \WCMusePOJO class a component by using @Component ? and we can not use any service inside the wcmusePOJO by using @Reference