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?
Solved! Go to Solution.
Views
Replies
Total Likes
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!
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!
Views
Likes
Replies