Expand my Community achievements bar.

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
Community Advisor

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

Community Advisor

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
Community Advisor

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