Expand my Community achievements bar.

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

Custom workflow LockException issue

Avatar

Level 2

I have implemented a custom AEM Workflow Process Step in Java that updates a JCR node property in the workflow payload path. Here’s my code snippet:

@component(service = WorkflowProcess.class, property = { "process.label=Update Payload Deep" })
public class UpdatePayloadProcess implements WorkflowProcess {

@reference
private ResourceResolverFactory resolverFactory;

@Override
public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap args) throws WorkflowException {
String payloadPath = workItem.getWorkflowData().getPayload().toString();

Map<String, Object> serviceUserMap = Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, "workflowServiceUser");

ResourceResolver resolver = null;
try {
resolver = resolverFactory.getServiceResourceResolver(serviceUserMap);

Session session = resolver.adaptTo(Session.class);

if (!session.nodeExists(payloadPath)) {
throw new WorkflowException("Payload path does not exist: " + payloadPath);
}

Node payloadNode = session.getNode(payloadPath);

// Lock the node before update to avoid conflicts in concurrent workflows
if (!payloadNode.isLocked()) {
session.getWorkspace().getLockManager().lock(payloadNode.getPath(), false, false, Long.MAX_VALUE, null);
}

payloadNode.setProperty("processedBy", "UpdatePayloadProcess");
session.save();

// Unlock the node after update
if (payloadNode.isLocked()) {
session.getWorkspace().getLockManager().unlock(payloadNode.getPath());
}

} catch (LoginException | RepositoryException e) {
throw new WorkflowException("Failed to update workflow payload", e);
} finally {
if (resolver != null && resolver.isLive()) {
resolver.close();
}
}
}
}

 

Despite implementing locking and proper service user access, sometimes the workflow fails with a LockException or concurrent update issues.
What could be the issue?

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @AnujaRa,

Could you try skipping the locking and instead use ResourceResolver with ModifiableValueMap to update the properties safely? As explicit JCR locking can cause deadlocks or stale locks, especially with concurrent workflows.

try (ResourceResolver resolver = resolverFactory.getServiceResourceResolver(serviceUserMap)) {
    Resource resource = resolver.getResource(payloadPath);
    if (resource != null) {
        ModifiableValueMap props = resource.adaptTo(ModifiableValueMap.class);
        props.put("processedBy", "UpdatePayloadProcess");
        resolver.commit();
    }
}

This approach lets AEM handle sessions and avoids locking problems.
References: 

Hope that helps!


Santosh Sai

AEM BlogsLinkedIn


View solution in original post

1 Reply

Avatar

Correct answer by
Community Advisor

Hi @AnujaRa,

Could you try skipping the locking and instead use ResourceResolver with ModifiableValueMap to update the properties safely? As explicit JCR locking can cause deadlocks or stale locks, especially with concurrent workflows.

try (ResourceResolver resolver = resolverFactory.getServiceResourceResolver(serviceUserMap)) {
    Resource resource = resolver.getResource(payloadPath);
    if (resource != null) {
        ModifiableValueMap props = resource.adaptTo(ModifiableValueMap.class);
        props.put("processedBy", "UpdatePayloadProcess");
        resolver.commit();
    }
}

This approach lets AEM handle sessions and avoids locking problems.
References: 

Hope that helps!


Santosh Sai

AEM BlogsLinkedIn