# Workflow Development

> Implement custom AEM Workflow Java components on AEM 6.5 LTS, including WorkflowProcess and ParticipantStepChooser with OSGi registration, metadata handling, and error patterns.

- Skill: `adobe/workflow-development` (Agent Skill, multi-file: 10 files)
- Install (CLI): `npx skillmds@latest add adobe/workflow-development`
- Raw SKILL.md: https://api.skillmd.com/api/skills/adobe/workflow-development/raw
- Safety review: PASS (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools, DevOps & Infra, Productivity, API Design, Deployment & Release
- Tags: Aem, Aem Workflow, Java, Jcr, Maven, Osgi, Sling
- License: Apache-2.0
- Author: Adobe (https://skillmd.com/u/adobe), verified publisher
- Updated: 2026-07-06
- Page: https://skillmd.com/skills/adobe/workflow-development

---


# Workflow Development (AEM 6.5 LTS)

> **Beta Skill**: This skill is in beta and under active development.
> Results should be reviewed carefully before use in production.
> Report issues at https://github.com/adobe/skills/issues

Implement custom workflow components for AEM 6.5 LTS: `WorkflowProcess`, `ParticipantStepChooser`, OSGi registration, metadata handling, and error patterns.

## Variant Scope

- AEM 6.5 LTS only.
- Both Felix SCR and DS R6 annotations are supported. DS R6 preferred for new code.
- Bundle deployed via Maven (`autoInstallBundle`) or Package Manager.

## Workflow

```text
Development Progress
- [ ] 1) Identify what the step does: process (auto) or participant (human) or dynamic participant
- [ ] 2) Create Java class implementing WorkflowProcess or ParticipantStepChooser
- [ ] 3) Register with @Component/@Service (Felix SCR) or @Component (DS R6) with service property
- [ ] 4) Read step arguments from MetaDataMap args
- [ ] 5) Access payload via item.getWorkflowData().getPayload().toString()
- [ ] 6) Read/write workflow instance metadata via item.getWorkflowData().getMetaDataMap()
- [ ] 7) Return normally to advance; throw WorkflowException to trigger retry
- [ ] 8) Deploy; verify process.label appears in Workflow Model Editor step picker
```

## WorkflowProcess Template — DS R6 (Preferred)

```java
@Component(
    service = WorkflowProcess.class,
    property = {
        "process.label=My Custom Process Step",
        "service.description=Short description"
    }
)
public class MyCustomProcess implements WorkflowProcess {

    @Reference
    private ResourceResolverFactory resolverFactory;

    @Override
    public void execute(WorkItem item, WorkflowSession session, MetaDataMap args)
            throws WorkflowException {
        String payloadPath = item.getWorkflowData().getPayload().toString();
        String myArg = args.get("myArgKey", "defaultValue");
        item.getWorkflowData().getMetaDataMap().put("processedBy", "my-step");
        // ... do work ...
    }
}
```

## WorkflowProcess Template — Felix SCR (Still Valid)

```java
@Component(metatype = false)
@Service(value = WorkflowProcess.class)
@Property(name = "process.label", value = "My Custom Process Step")
public class MyCustomProcess implements WorkflowProcess {

    @Reference
    private SlingRepository repository;

    @Override
    public void execute(WorkItem item, WorkflowSession session, MetaDataMap args)
            throws WorkflowException {
        // same body as DS R6 example
    }
}
```

## ParticipantStepChooser Template

```java
@Component(
    service = ParticipantStepChooser.class,
    property = {"chooser.label=Department Head Chooser"}
)
public class DepartmentHeadChooser implements ParticipantStepChooser {

    @Override
    public String getParticipant(WorkItem workItem, WorkflowSession session,
                                 MetaDataMap args) throws WorkflowException {
        String department = workItem.getWorkflowData()
                                    .getMetaDataMap().get("department", "marketing");
        return department + "-managers";
    }
}
```

## Guardrails

- Never use `loginAdministrative()`. Always use a service user mapped via `ServiceUserMapper`.
- Felix SCR: keep `metatype=false` unless exposing configuration to the OSGi console.
- Do not mix Felix SCR and DS R6 annotations in the same class.
- Throw `WorkflowException` for retryable errors; log and rethrow for unexpected errors.

## References

- [process-step-patterns.md](./references/workflow-development/process-step-patterns.md) — WorkflowProcess patterns with Felix SCR and DS R6 examples
- [participant-step-patterns.md](./references/workflow-development/participant-step-patterns.md) — ParticipantStepChooser patterns and completing steps
- [variables-and-metadata.md](./references/workflow-development/variables-and-metadata.md) — MetaDataMap, workflow variables, inter-step data
- [api-reference.md](./references/workflow-foundation/api-reference.md)
- [65-lts-guardrails.md](./references/workflow-foundation/65-lts-guardrails.md)

