1

I get a nullpointer exception in error logs when I use subservice to read a template's details in AEM 6.4

map.get gives null-pointer exception

with error message as

com.adobe.cq.sightly.WCMUsePojo Failed to activate Use class java.lang.IllegalArgumentException: javax.jcr.RepositoryException: This session has been closed. at org.apache.sling.jcr.resource.internal.JcrValueMap.readFully(JcrValueMap.java:395) [org.apache.sling.jcr.resource:3.0.8] at org.apache.sling.jcr.resource.internal.JcrValueMap.entrySet(JcrValueMap.java:183) [org.apache.sling.jcr.resource:3.0.8] at com.mysite.core.helpers.AnalyticsHelper.activate(AnalyticsHelper.java:138) [mysite-core:1.0.0.SNAPSHOT] at com.adobe.cq.sightly.WCMUsePojo.init(WCMUsePojo.java:86) [com.adobe.cq.sightly.cq-wcm-sightly-extension:1.5.12]

it ran fine in AEM 6.3, but in AEM 6.4, it gives null pointer exception

the map is null . It works fine when I remove closing the resourceresolver

MysiteReadTemplateService mysiteReadTemplateService = getSlingScriptHelper()
                .getService(MysiteReadTemplateService .class);
        ValueMap map = mysiteReadTemplateService 
                .fetchTemplateDetails(templatePath);
        if (map != null) {
            templateName = map.get("jcr:title", "");
            templateDescription = map.get("jcr:description", "");
        }

inside fetchTemplateDetails method -

Map<String,Object> paramMap = new HashMap<String,Object>();
          //Mention the subServiceName that is configured in the User Mapping
          paramMap.put(ResourceResolverFactory.SUBSERVICE, "mysitereadservice");
          log.info("After the param");
          ResourceResolver rr = null;
          ValueMap map =null;
          try{
                rr = resourceFactory.getServiceResourceResolver(paramMap);
                log.info("UserId : " + rr.getUserID());
                Resource templateResource = rr.getResource(templatePath);
                log.info("Resource : " + templateResource.getPath());
                map = templateResource.getValueMap();  
                rr.close();
          }catch(Exception e){
                log.error(e.getMessage());
          }
          return map;

when rr.close is commented, map is not null in analyticshelper class.

possible explanation is provided in

com.sun.jdi.InvocationException occurred invoking method

but still, we want to close the resourceresolver as not closing it will create many unclosed sessions .

If anybody faced same issue, could you please let us know your thoughts, or how can I refactor the code so that we are able to close resource resolver as well as the map is not null.

cqsapientuser
  • 65
  • 3
  • 12
  • ValueMap, Resource and etc is unavailable after you close session, put data from ValueMap into any data structure like HashMap and use it in another method/class – dzenisiy Sep 10 '18 at 11:20

1 Answers1

0

You can't access resources or properties(ValueMap) after you closed the sesssion/resourceResolver. Put your data into another data structure(Collection, Map) and return it. Or perform your actions while session is opened:

Map<String, Object> result = new HashMap<String, Object>;
ResourceResolver rr = null;

try{
    Map<String,Object> paramMap = new HashMap<String,Object>();
    //Mention the subServiceName that is configured in the User Mapping
    paramMap.put(ResourceResolverFactory.SUBSERVICE, "mysitereadservice");
    log.info("After the param");
    rr = resourceFactory.getServiceResourceResolver(paramMap);

    if (rr != null) {
        log.info("UserId : " + rr.getUserID());

        Resource templateResource = rr.getResource(templatePath);

        if (templateResource != null) {
            log.info("Resource : " + templateResource.getPath());
            ValueMap map = templateResource.getValueMap();  

            result.put("jcr:title", map.get("jcr:title",""))
            result.put(......);
            result.put(......);
            result.put(......);
            result.put(......);
            result.put(......);
        }
    }
}catch(LoginException e){
    log.error(e.getMessage(), e);
} finally {
    if (rr != null && !rr.isLive()) {
        rr.close();
    }
}

return result;

ResourceResulver should be closed in finally block, or use try-with-resources:

try (ResourceResolver rr = resourceFactory.getServiceResourceResolver(paramMap)) {
    //yourCode
} catch (LoginException e) {
    log.errror(e.getMessage(), e);
}
dzenisiy
  • 855
  • 10
  • 32