Custom workflow LockException issue | Community
Skip to main content
Level 2
May 22, 2025
Solved

Custom workflow LockException issue

  • May 22, 2025
  • 1 reply
  • 411 views

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:

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

@3214626
private ResourceResolverFactory resolverFactory;

@9944223
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?

Best answer by SantoshSai

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!

1 reply

SantoshSai
Community Advisor
SantoshSaiCommunity AdvisorAccepted solution
Community Advisor
May 22, 2025

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