Mastering Scheduled Sling Jobs in AEMAsCloud

In Adobe Experience Manager (AEM), automation is key to maintaining performance, consistency and efficiency. Whether it’s clearing caches, syncing content, or sending periodic reports, automating repetitive tasks can save time and reduce errors.

When your tasks involve long-running or distributed processes, AEM’s Sling JobManager provides a reliable framework for creating and managing background jobs.

One of the most powerful and flexible ways to automate such tasks is through Scheduled Sling Jobs.
In this post, we’ll explore what they are, when to use them, and how to implement both recurring and one-time jobs — including a working “later” scheduling solution that actually runs on AEM as a Cloud Service.

🧠When and Why to use Sling Jobs:-

A Sling Job in AEM is a background task managed by the Apache Sling Job Handling framework. It’s used to execute jobs asynchronously and reliably within the AEM environment.

By using scheduled jobs smartly, you can:

  • Offload repetitive background operations.
  • Improve overall system performance.
  • Ensure a consistent digital experience across environments.
  • Free up developers from manual or time-sensitive interventions.

Common Use Cases

  • Nightly content replication between author and publish instances.
  • Daily analytics data export to external systems.
  • Periodic cache invalidation for stale pages.
  • Automated notifications to authors or administrators

⚙️Creating a Scheduled Sling Job in AEM

AEM supports two main approaches for scheduling jobs, depending on your requirement:

  1. Using Cron Expressions (Recurring Jobs)
  2. Using “Later” Option (One-Time or Delayed Execution)

Let’s explore both with working code examples.

⏱️ 1. Cron Expression-Based Scheduling

This approach is ideal for tasks that must run at recurring, fixed intervals — such as every few minutes, hourly, daily, or weekly.

Best Use Cases

  • Regular maintenance tasks: Purging old logs, cleaning temporary files, syncing data, etc.
  • Timed publishing/unpublishing: Automatically publish or unpublish pages at a given time.
  • Report generation: Produce daily or weekly content or analytics reports.
  • Data processing: Aggregate statistics or refresh search indexes at scheduled times.

Sample Code:-

package com.example.core.schedulers;

import org.apache.sling.commons.scheduler.ScheduleOptions;
import org.apache.sling.commons.scheduler.Scheduler;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(service = Runnable.class, immediate = true)
public class ExampleScheduledJob implements Runnable {

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

    @Reference
    private Scheduler scheduler;

    private static final String JOB_NAME = "com/example/core/schedulers/ExampleScheduledJob";

    @Activate
    protected void activate() {
        LOG.info("Activating ExampleScheduledJob...");
        ScheduleOptions options = scheduler.EXPR("0 0/5 * * * ?"); // Runs every 5 minutes
        options.name(JOB_NAME);
        options.canRunConcurrently(false);
        scheduler.schedule(this, options);
    }

    @Deactivate
    protected void deactivate() {
        LOG.info("Deactivating ExampleScheduledJob...");
        scheduler.unschedule(JOB_NAME);
    }

    @Override
    public void run() {
        LOG.info("Scheduled Job is running...");
        // Add your logic here (e.g., cleanup, sync, notifications)
    }
}

2. The “Later” Option (One-Time / Delayed Execution)

Sometimes, you need to execute a job once at a specific future date and time — not on a repeating schedule.

  • 🎯 One-time content releases: Schedule a content update to go live at a future time.
  • ✉️ Event-driven actions: Trigger a marketing campaign or notification after an event.
  • Delayed processing: Execute a job after a defined waiting period (e.g., 30 minutes later).

Sample Code

package com.example.core.schedulers;

import org.apache.sling.event.jobs.Job;
import org.apache.sling.event.jobs.JobManager;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Component(service = OneTimeJobScheduler.class, immediate = true)
public class OneTimeJobScheduler {

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

    @Reference
    private JobManager jobManager;

    private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

    /**
     * Schedule a Sling job to run once after a delay (in minutes).
     */
    public void scheduleOneTimeJob(long delayMinutes) {
        scheduler.schedule(() -> {
            Map<String, Object> props = new HashMap<>();
            props.put("custom.property", "value");

            Job job = jobManager.addJob("com/example/one-time-job", props);
            if (job != null) {
                LOG.info("Scheduled one-time job executed: {}", job.getId());
            } else {
                LOG.error("Failed to create one-time job");
            }

        }, delayMinutes, TimeUnit.MINUTES);

        LOG.info("Job will be triggered once after {} minutes", delayMinutes);
    }

    /**
     * Optionally shut down scheduler (if needed)
     */
    public void deactivate() {
        scheduler.shutdown();
    }
}

The above code is the only working code that i found after spending good amount of time , that’s why i decide to put here in this blog to help fellow AEM community members.

There are lot of code suggestion you will get on internet for using Later option in AEMASCloud but 99% of them are not going to work. below i am listing few that every one suggested but are not working.

⚠️ Common Mistakes — What Not to Do

If you’ve tried to implement delayed jobs in AEM as a Cloud Service, you’ve probably seen dozens of code snippets online that don’t actually work.

// ❌ Wrong: "AT" method doesn’t exist
scheduler.schedule(job, scheduler.AT(futureDate));
// Error: Cannot resolve method 'AT' in 'ScheduledExecutorService'

// ❌ Wrong: Incorrect JobManager parameters
jobManager.addJob(JOB_TOPIC_NAME, null, jobProps, delayInMillis);
// Error: 'addJob(java.lang.String, java.util.Map)' cannot be applied to '(String, null, Map, long)'

// ❌ Wrong: Using non-existent 'delay' method
jobManager.createJob("job/topic")
          .properties(jobProps)
          .delay()
          .add();
// Error: Cannot resolve method 'delay' in 'JobBuilder'

// ❌ Wrong: ScheduleInfo always null
ScheduledJobInfo scheduleInfo = jobManager.createJob("job/topic")
          .properties(jobProps)
          .schedule()
          .at(startTime)
          .add();
// No exception, but job never executes — scheduleInfo is always null

These examples are widely circulated but not compatible with AEM as a Cloud Service.
The working approach shown earlier — using a ScheduledExecutorService with JobManager.addJob() — is currently the most reliable and practical solution.

💡 Key Takeaways

  • Use cron-based Sling Jobs for recurring, fixed-interval tasks.
  • Use one-time job scheduling (later) for delayed or single execution tasks.
  • Avoid deprecated or unsupported scheduling APIs — especially in AEM Cloud environments.
  • Always log and monitor your scheduled jobs for visibility and debugging.

❤️ Final Thoughts

The examples shared here come from real-world AEM Cloud implementations — tested and verified after much trial and error.

I decided to publish this post to help fellow AEM developers save time and frustration.
If you’ve struggled to get the “later” option working, you’re not alone — but with this approach, your scheduled jobs should now work smoothly in both on-prem and AEM as a Cloud Service environments.

Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.