Expand my Community achievements bar.

Submissions are now open for the 2026 Adobe Experience Maker Awards.
SOLVED

OSGi config(Environment variable) not picked up in cloud

Avatar

Level 1

Hi Community,

I have a simple service with an OSGi config. After deploying, the service always uses defaults what I have in code - not picking from the environment valiables.

Here is my code

package com.acme.core.schedulers;

import org.apache.sling.commons.scheduler.Scheduler;
import org.osgi.service.component.annotations.*;
import org.osgi.service.metatype.annotations.*;

@component(service = Runnable.class, immediate = true)
@Designate(ocd = ACLCleanpSchedulerConfig.class) // not a factory
public class ACLCleanpScheduler implements Runnable {

@ObjectClassDefinition(name = "Acme - ACL Cleanp Scheduler")
public @interface ACLCleanpSchedulerConfig {
@AttributeDefinition(name="Enabled")
boolean enabled() default false;

@AttributeDefinition(name="Cron")
String cron() default "0/10 * * * * ?";

@AttributeDefinition(name="Base Path")
String base_path() default "/content/dam";
}

@reference private Scheduler scheduler;
private volatile ACLCleanpSchedulerConfig cfg;

@activate @MODIFIED
protected void activate(ACLCleanpSchedulerConfig cfg) throws Exception {
this.cfg = cfg;
scheduler.unschedule("acme-aclcleanp");
if (cfg.enabled()) {
scheduler.schedule(this, scheduler.EXPR(cfg.cron()), true);
}
}

@deactivate
protected void deactivate() throws Exception {
scheduler.unschedule("acme-aclcleanp");
}

@Override public void run() {
// cleanup work using cfg.base_path()
}
}

 

/apps/acme/osgiconfig/config/com.acme.core.schedulers.ACLCleanpScheduler.cfg.json
{
"enabled":"$[env:ACL_ENABLED;default=false]",
"cron": "$[env:ACL_CRON;default=0/50 * * * * ?]",
"base_path": "$[env:ACL_BASE_PATH;default=/content/dam/]"
}

Note: I have set the environment variables on the configurations already.

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @rakesh_mallel,

It looks good to me except one thing where I suspect:

Can you try to set the configuration property from base_path to base.path (dot instead underscore)?

{
  "enabled":"$[env:ACL_ENABLED;default=false]",
  "cron": "$[env:ACL_CRON;default=0/50 * * * * ?]",
  "base.path": "$[env:ACL_BASE_PATH;default=/content/dam/]"
}

 


Santosh Sai

AEM BlogsLinkedIn


View solution in original post

7 Replies

Avatar

Community Advisor

Hi @rakesh_mallel ,

 

First of all, in the AEMaaCS you must not use Sling Commons Scheduler for scheduling as execution cannot be guaranteed. It is just more likely that it is scheduled. Official documentation: https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/dev... 

 

In addition, I would recommend to have env variable as String.

 

Refactored code and best practice:

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.sling.event.jobs.Job;
import org.apache.sling.event.jobs.JobBuilder;
import org.apache.sling.event.jobs.JobManager;
import org.apache.sling.event.jobs.ScheduledJobInfo;
import org.apache.sling.event.jobs.consumer.JobConsumer;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

import java.util.Collection;
import java.util.Optional;

import static ACLCleanpScheduler.TOPIC;


@Component(
        service = {JobConsumer.class},
        immediate = true,
        property = {JobConsumer.PROPERTY_TOPICS + "=" + TOPIC},
        configurationPolicy = ConfigurationPolicy.REQUIRE
)
@Designate(ocd = ACLCleanpScheduler.ACLCleanpSchedulerConfig.class)
@Slf4j
public class ACLCleanpScheduler implements JobConsumer {

    public static final String TOPIC = "acme-aclcleanp";

    @ObjectClassDefinition(name = "Acme - ACL Cleanp Scheduler")
    public @interface ACLCleanpSchedulerConfig {

        @AttributeDefinition(name = "Enabled")
        String enabled() default "false";

        @AttributeDefinition(name = "Cron")
        String cron() default "0/10 * * * * ?";

        @AttributeDefinition(name = "Base Path")
        String base_path() default "/content/dam";

    }

    private volatile ACLCleanpSchedulerConfig cfg;

    @Reference
    private transient JobManager jobManager;

    @Activate
    @Modified
    protected void activate(ACLCleanpSchedulerConfig cfg) throws Exception {
        this.cfg = cfg;
        if (!Boolean.parseBoolean(cfg.enabled())) {
            return;
        }
        startScheduledJob();
    }

    private void unScheduleExistingJobs() {
        Optional.ofNullable(jobManager.getScheduledJobs(TOPIC, 0, null))
                .orElse(CollectionUtils.emptyCollection())
                .forEach(job -> {
                    log.info("Removing Scheduler Job '{}'", job.getJobTopic());
                    job.unschedule();
                });
    }

    private void startScheduledJob() {
        unScheduleExistingJobs();
        Collection<ScheduledJobInfo> myJobs = jobManager.getScheduledJobs(TOPIC, 0, null);
        log.info("Initiating scheduled job with CRON expression: {}", cfg.cron());
        if (!myJobs.isEmpty()) {
            log.error("Can't schedule any existing scheduled jobs, because there are already scheduled");
            return;
        }
        JobBuilder.ScheduleBuilder scheduleBuilder = jobManager.createJob(TOPIC).schedule();
        scheduleBuilder.cron(cfg.cron());
        if (scheduleBuilder.add() == null) {
            log.error("Job '{}' was not scheduled", TOPIC);
            return;
        }
        log.info("Job has been scheduled successfully");
    }

    @Override
    public JobResult process(Job job) {
        return JobResult.OK;
    }

}

 

Kostiantyn Diachenko


Check out AEM VLT Intellij plugin


Hi @konstantyn_diachenko Thank you for your response - I have no issues in running scheduler, everyhting works well as expected but only issue is it's not reading the value from environment variables.

 

Also, I tried the same code as you pasted above but still not working specially base path is setting from the code which I have set as default here: String base_path() default "/content/dam"; where I have set /content/dam/acme/ in environment variable. Any idea? appreciate your help.

Avatar

Level 10

Have you tried removing the part

default "/content/dam"

from the code?

Have you checked if this issue occurs in other OSGI services? The configuration file appears to be fine (source), but please review it to see if you overlooked something.

 

 

 

Avatar

Level 1

Yes, I did removed from the code too, just to double check but no luck - either it's empty or default from the code.

Avatar

Community Advisor

Hi @rakesh_mallel ,

 

@SantoshSai  made a good catch. In the OSGi R7 there is a mapping for Java annotation method to OSGi property:

Left: annotation method symbols
Right: replacement in the property name

"__" to "_",
"_" to ".",
"\$_\$" to "-",
"\$\$" to "\$",
"\$" to ""

 

So, please define OSGi property in the .cfg.json file as "base.path".

 

In addition, I would recommend to get rid of scheduler and start using Sling Jobs. I referenced an official documentation.

Kostiantyn Diachenko


Check out AEM VLT Intellij plugin


Avatar

Correct answer by
Community Advisor

Hi @rakesh_mallel,

It looks good to me except one thing where I suspect:

Can you try to set the configuration property from base_path to base.path (dot instead underscore)?

{
  "enabled":"$[env:ACL_ENABLED;default=false]",
  "cron": "$[env:ACL_CRON;default=0/50 * * * * ?]",
  "base.path": "$[env:ACL_BASE_PATH;default=/content/dam/]"
}

 


Santosh Sai

AEM BlogsLinkedIn


Avatar

Level 1

@SantoshSai This worked, thank you!