JCR Session comes back null in custom Workflow step implementation | Community
Skip to main content
marissaw9851252
Level 3
October 16, 2015
Solved

JCR Session comes back null in custom Workflow step implementation

  • October 16, 2015
  • 11 replies
  • 4207 views

I have created a custom Workflow step for AEM 6.0.  I created a class that implements com.adobe.granite.workflow.exec.WorkflowProcess.  I need to get the jcr session and session.adaptTo(Session.class) is returning null.  session is not null and its type is com.adobe.granite.workflow.WorkflowSession.  The example in the Extending Workflow Functionality documentation uses this call to get the jcr session. http://docs.adobe.com/docs/en/aem/6-0/develop/extending/workflows/wf-extending.html

Below is the class declaration and the first part of the execute method.  This custom Workflow step is set up in place of the Product Asset Upload step at the end of the DAM Update Asset Workflow. 

@Component
@Service(value = WorkflowProcess.class)
@Properties({
 @Property(name = "process.label", value = "Custom Product Assets Upload Process"),
 @Property(name = Constants.SERVICE_DESCRIPTION, value = "Custom Product Assets Upload Process"),
 @Property(name = Constants.SERVICE_VENDOR, value = "Test")
})
public class CustomProductAssetsUploadProcess implements com.adobe.granite.workflow.exec.WorkflowProcess{
 
 private static final String TYPE_JCR_PATH = "JCR_PATH";
    private static final Logger log = LoggerFactory.getLogger(CustomProductAssetsUploadProcess.class);
    public static final String ENABLE_WRITEBACK = "writebackEnable";
 
    @Reference(cardinality= ReferenceCardinality.MANDATORY_UNARY, policy = ReferencePolicy.STATIC)
    private ResourceResolverFactory resourceResolverFactory;
   
    public void execute(WorkItem item, WorkflowSession session, MetaDataMap args) throws WorkflowException {

        try {
           String payloadPath = null;

            if (item.getWorkflowData().getPayloadType().equals(TYPE_JCR_PATH)) {
                payloadPath = item.getWorkflowData().getPayload().toString();
            }
                       
            log.info("payload path :"+payloadPath);
                       
            Session jcrSession = session.adaptTo(Session.class);

...

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by WillMc1

Hmm...

Is there any chance you are embedding a dependency jar inside your bundle?  If you have your own copy of the javax.jcr.Session class file inside your bundle the classloaders could be messed up.  

Sorry again just a guess.

Will

11 replies

smacdonald2008
Level 10
October 16, 2015

As of AEM 6, you get a session instance (required to work with the JCR API) by using a Sling method named getServiceResourceResolver().


 The following code shows use of the more secure getServiceResourceResolverAPI call.

Map<String, Object> param = new HashMap<String, Object>();
param.put(ResourceResolverFactory.SUBSERVICE, "datawrite");
ResourceResolver resolver = null;

try {
           
    //Invoke the adaptTo method to create a Session used to create a QueryManager
resolver = resolverFactory.getServiceResourceResolver(param);
    session = resolver.adaptTo(Session.class);

This code uses a specific AEM account with JCR read and write privileges to access the AEM 6 JCR. For more infor, see this community article

http://helpx.adobe.com/experience-manager/using/querying-experience-manager-sling.html
 

Adobe Employee
October 16, 2015

Please check if you are using correct API to access the session. The OOTB code still uses old com.day.cq.workflow.WorkflowSession; code

while the example recommend using  com.adobe.granite.workflow.WorkflowSession;

http://docs.adobe.com/docs/en/cq/5-3/javadoc/com/day/cq/workflow/WorkflowSession.html 

Adobe Employee
October 16, 2015

I tried to reproduce this and could not. If you log the session object, what do you get?

Regards,

Justin

Adobe Employee
October 16, 2015

Hi,

Shot in the dark here - wondering what the import for the Session class you are using is in your original example. Is there any chance you've got the wrong Session specified?

You should always be able to adapt a com.adobe.granite.worklfow.WorkflowSession to a javax.jcr.Session

Will

marissaw9851252
Level 3
October 16, 2015

The import for the Session class I am trying to adapt to is: import javax.jcr.Session;

marissaw9851252
Level 3
October 16, 2015

This is what I get when I log the WorkflowSession object.

06.02.2015 09:50:46.121 *INFO* [JobHandler: /etc/workflow/instances/2015-02-06/model_320814424647979:/content/dam/projects/test10/incoming/Test Photoshoot.zip/jcr:content/renditions/original] com.custom.dam.bl.services.CustomProductAssetsUploadProcess com.adobe.granite.workflow.core.WorkflowSessionImpl@40ee7b69

smacdonald2008
Level 10
October 16, 2015

Did you use the getServiceResourceResolver()method to get a session object in the custom Workflow step? 

WillMc1Adobe EmployeeAccepted solution
Adobe Employee
October 16, 2015

Hmm...

Is there any chance you are embedding a dependency jar inside your bundle?  If you have your own copy of the javax.jcr.Session class file inside your bundle the classloaders could be messed up.  

Sorry again just a guess.

Will

marissaw9851252
Level 3
October 16, 2015

That fixed it.  I accidentally had that dependency in my pom file.  Thanks for the help.

I'm running into another issue in the code below.  

Asset asset = null;
        if (item.getWorkflowData().getPayloadType().equals("JCR_PATH")) {
            String path = item.getWorkflowData().getPayload().toString();
            //Resource resource = this.getResourceResolver(session).getResource(path);
            Resource resource = resourceResolver.getResource(path);            
            if (null != resource) {
                asset = DamUtil.resolveToAsset(resource);
            }
            else {
                log.error("getAssetFromPaylod: asset [{}] in payload of workflow [{}] does not exist.", path, item.getWorkflow().getId());
            }
        }
        return asset;

DamUtil.resolveToAsset(resource) is throwing an exception.  I think this may be a dependency issue as well.  Here is the exception:

com.adobe.granite.workflow.WorkflowException: Process execution resulted in an error
    at com.adobe.granite.workflow.core.job.HandlerBase.executeProcess(HandlerBase.java:218)
    at com.adobe.granite.workflow.core.job.JobHandler.process(JobHandler.java:140)
    at org.apache.sling.event.jobs.JobUtil$1.run(JobUtil.java:365)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.LinkageError: loader constraint violation: when resolving method "com.day.cq.dam.commons.util.DamUtil.resolveToAsset(Lorg/apache/sling/api/resource/Resource;)Lcom/day/cq/dam/api/Asset;" the class loader (instance of org/apache/felix/framework/BundleWiringImpl$BundleClassLoaderJava5) of the current class, com/custom/dam/bl/services/customProductAssetsUploadProcess, and the class loader (instance of org/apache/felix/framework/BundleWiringImpl$BundleClassLoaderJava5) for resolved class, com/day/cq/dam/commons/util/DamUtil, have different Class objects for the type ling/api/resource/Resource;)Lcom/day/cq/dam/api/Asset; used in the signature
    at com.custom.dam.bl.services.customProductAssetsUploadProcess.getAssetFromPayload(CustomProductAssetsUploadProcess.java:181)
    at com.custom.dam.bl.services.customProductAssetsUploadProcess.execute(CustomProductAssetsUploadProcess.java:116)
    at com.adobe.granite.workflow.core.job.HandlerBase.executeProcess(HandlerBase.java:212)
    ... 5 common frames omitted

marissaw9851252
Level 3
October 16, 2015

I just tried that.  I am getting an error in the log "Login Failure: all modules ignored".  I completed the following to test this out:

1.  I added a user with the login = "data" and gave them  the necessary permissions.

2.  I updated the configuration for the Apache Sling Service User Mapper Service to include the following entry:

com.custom.dam.bl.services.CustomProductAssetsUploadProcess:datawrite=data

 

3.  I added the following code:

Map<String, Object> param = new HashMap<String, Object>();
param.put(ResourceResolverFactory.SUBSERVICE, "datawrite");
ResourceResolver resolver = null;
try{      
         resolver = resourceResolverFactory.getServiceResourceResolver(param);

...