Custom AEM Workflow Launchers for Page Property Changes

Adelaide's AEM practitioners often joke that the moment a campaign goes live, somebody changes a hero image and the content tree decides to misbehave. Workflow launchers quietly prevent that chaos by listening to the JCR for the events you care about and firing automation the moment those events arrive. When the trigger is a page property change, the launcher becomes the bridge between editorial intent and downstream systems like translation services, search indexers, or notification queues.

Adobe Experience Manager exposes launchers as repository nodes under /conf/global/settings/workflow/launchers, and most teams leave the defaults alone because they ship working. The defaults handle content changes inside /content but rarely fire on the metadata that genuinely matters for governance: a regulatory flag, a publication blackout window, or a brand variant. Tightening a launcher to watch a specific property path is a pattern that pays off quickly in any CIRCUIT-style technical session.

This walk-through assumes you already write OSGi components and have a working AEM 6.x instance. The focus is the launcher configuration, the workflow model you wire it to, and the process steps that turn a property value into a meaningful business action.

Understanding How Launchers React to Repository Events

A launcher is a declarative bridge between an Observation listener and a workflow model. When a node is added, modified, or removed under a watched path, the launcher evaluates its conditions and, if they pass, hands the affected payload to the workflow runtime. The runtime creates a workflow instance, loads the model, and steps through the process graph.

The condition node accepts XPath, a glob path, and a property-existence check. Out of the box the path is usually set to /content/dam or /content/, which is why a launcher fires the moment any component is touched. Tightening this to a property path such as /content/wknd/en/./jcr:content/brandVariant narrows the firing surface dramatically. Teams at a Perth-based retailer found that moving from path-only filtering to property comparison cut weekly launcher executions by more than 80 percent.

Selecting EVENT_TYPE_MODIFIED ensures the launcher reacts only to genuine edits, sparing the workflow engine from the noise of asset ingestion or bulk imports.

Mapping the Property Path You Want to Watch

The most common mistake is treating the property path as if it were a content path. A page property lives on the jcr:content node, not on the page itself. That distinction catches out developers in Melbourne who assume /content/wknd/en/about-us maps directly to the title field they see in the editor.

The correct pattern is to anchor the watcher on the jcr:content child and qualify the property name. A launcher that should fire when the regulatoryFlag property flips from internal to public would use a glob like /content/wknd/.*/jcr:content and rely on its condition node to assert the property name and value. A glob keeps the launcher portable across language copies and brand sites, useful when you run a shared instance for APRA-regulated entities and consumer brands.

Sketch the property tree of a representative page in CRXDE Lite before committing to a path. The set is usually smaller than you think, and each entry becomes a candidate for either its own launcher or its own branch inside a single workflow model.

Building the Workflow Model Around the Trigger

Once the launcher fires, control passes to a workflow model. For property-driven automation the model is usually short: a few decision points, a process step or two, and an end node. Modelling it as a separate workflow from your long-running editorial approvals keeps response time in the low seconds, which matters when an editor in Adelaide is watching for visual confirmation that the change took effect.

Inside the model, a custom process step written in Java receives the payload, the workflow metadata, and the resource resolver. From there you can read the current value of the watched property, compare it against the previous value that JCR exposes through observation events, and route the workflow accordingly. A typical pattern is to call a small service that publishes a JMS message, updates a search index, or flags the page in a downstream compliance dashboard.

If your team already uses Jenkins to validate OSGi bundles before deployment, the same launch-and-listen pattern can be repurposed to gate a content change before it goes live. Many Sydney agencies extend this idea further with Jenkins build pipelines that promote a launcher-configured workflow from staging straight into production.

Adding Conditional Logic Inside the Process Step

A launcher with a generous glob fires for many properties, so the process step almost always ends up being a small switchboard. Pulling the property name from the payload metadata lets you branch on regulatoryFlag, blackoutWindow, or embargoLift without spinning up a separate workflow for each. The switchboard should default to a no-op so that adding a new property in the future does not silently trigger downstream systems.

Branching by value is where the real payoff lives. A regulatory flag transition from internal to public may need to clear the page through a legal review workflow, while the reverse transition can simply notify the content owner. Encoding both directions inside the same launcher keeps the configuration in one place and makes the behaviour obvious to the next developer who opens CRXDE Lite. Australian English spellings like "authorise" and "organisation" often surface in property names, so be deliberate about consistency in the dictionary your service layer consults.

Enrich the workflow payload with a small JSON document describing the before-and-after state, and downstream services receive enough context to act without querying AEM a second time. This pattern pairs well with versioning rules, as outlined in component versioning workflows, where every meaningful change should leave a recoverable trail.

Testing on Author and Publish Without Burning the Logs

Launchers run on the author tier by default, and there is a good reason for that: a publish-tier launcher creates unbounded workflow instances for every consumer request. The trap is that teams in Brisbane sometimes copy a launcher node from author to publish when troubleshooting, only to discover weeks later that the publish instance is silently accumulating failed jobs.

A cleaner testing pattern is to mirror the launcher configuration into a dedicated test author instance that points at a stubbed publish. Run the launcher, observe the workflow payload, and assert on the side effects through a mocked downstream service. Once the path is stable, promote the configuration through your normal package pipeline rather than touching the production repository directly.

If you need to validate the launcher's behaviour on publish for genuine cross-tier scenarios, gate it behind a run-mode condition that reads an OSGi configuration flag rather than a hard-coded boolean. The same bundle can then ship to author, stage, and publish with the launcher effectively disabled everywhere except the tier you intend.

Comparing Launch Strategies for Page Property Changes

Choosing the right launcher pattern is a trade-off between flexibility and traceability. Path-based defaults are easy to configure but generate noise. A custom glob with a property condition keeps things tidy and is the right starting point for editorial properties. A JCR observation listener written as an OSGi service unlocks logic that launchers cannot express, at the cost of bypassing the workflow UI.

Strategy Best Use Case Fits Well With Watch Out For
OOTB path-based launcher Any change under a content subtree DAM ingestion, broad audits High noise, fires on every component edit
Custom glob plus property condition A single named property across language copies Translation triggers, compliance flags Glob misconfiguration can swallow sibling sites
JCR observation listener as a service Complex multi-property logic that launchers cannot express Reindexing, external sync Bypasses workflow UI, harder to audit
Hybrid launcher plus external rule engine Regulated industries needing full traceability APRA and Privacy Act scenarios Adds an external runtime dependency

Choose based on the questions your auditors and operators will ask. If they want to replay every step from a workflow dashboard, stay with a launcher-driven workflow. Most teams land on a hybrid: launchers for declared, auditable work, and observation listeners for low-level plumbing.

Tuning Performance and Avoiding Common Pitfalls

A launcher that fires thousands of times per hour quietly saturates the workflow queue and starves other models. The two levers that almost always matter are the condition node and the workflow throttling configuration. Tightening the condition to a single property is the cheapest win; reducing the launcher thread count or adding a coalesce window is the second.

Watch for circular triggers as well. A launcher that updates the property it listens to will fire itself in an infinite loop unless the process step writes to a different path or uses an OSGi flag to mark the change as launcher-generated. A simple boolean like internal:launcherProcessed on the payload resource breaks the cycle and keeps the system stable through a Black Friday-style content rush.

Document every custom launcher in the same place you keep OSGi service notes, with a short entry listing the watched path, the trigger event, the workflow model, and an owner. Australian teams across Melbourne, Sydney, and remote hubs find this habit valuable because the on-call rotation often crosses state borders and AEST/AEDT boundaries.

Browse the recorded sessions from the 2015 and 2016 CIRCUIT conferences to see how other AEM practitioners approached launchers, integrations, and architectural decisions in production. Submit your own launcher patterns into the speaker notes for the next call for papers and help the next cohort of developers skip the missteps you have already lived through.