Sling models and resource resolver- AutoClosable? | Community
Skip to main content
Level 9
January 1, 2023
Solved

Sling models and resource resolver- AutoClosable?

  • January 1, 2023
  • 2 replies
  • 3541 views

Hi all,

on  AEM 6.5.12

i May have asked this question but maybe to get a confirmation if I have a sling model and adapt to Resource.class , 

In it I have @586265 for resourceresolver . 
i use it in one of the getter methods as resourceResolver.map(path) . I am not using post constructs 


do I have to close the resource resolver at any point in a sling model class ? Does it automatically close it at the end of the usage of model class ? Trying to avoid session leaks.

 

 I am not passing the resource resolver to any class but using it for map however I even have some logic for externalizing post mapping 

the customExternalizerService has another service resolver that opens where path is sent over. Model’s resolver is not passed 



 

@Model(adaptables = Resource.class)
public class PageModel {

@Self
private Resource resource 

 

@586265

private ResourceResolver resolver;

 

@586265

private customExternalizerService customExternalizerService;

 

private String extPageUrl;



public String getExtPageUrl() {
PageManager pageManager= resolver.adaptTo(PageManager.class);
Page currentPage = pageManager.getContainingPage(resource);
this. extPageUrl = customExternalizerService.externalize(resolver.map(currentPage.getPath());
return this.extPageUrl;
}

}

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 lukasz-m

Hi @nitrohazedev,

There is no need to close ResourceResolver injected that way into Sling Model, or retrieved via request.getResourceResolver(), request.adaptTo(ResourceResolver.class) or resource.getResourceResolver().

In above case you are not creating new instance of ResourceResolver this is why you do not have to close it explicitly.

However you will have to close ResourceResolver in Sling Model if you will create new instance of it using ResourceResolverFactory.

One remark to your implementation. I would suggest to use specific annotation/injector to get ResourceResolver object. It is also mentioned under Sling documentation

 

// use @SlingObject private ResourceResolver resourceResolver; // instead of @Inject private ResourceResolver resourceResolver;

 

 This is recommended due to performance reasons, more can be found under:

2 replies

lukasz-m
Community Advisor
lukasz-mCommunity AdvisorAccepted solution
Community Advisor
January 1, 2023

Hi @nitrohazedev,

There is no need to close ResourceResolver injected that way into Sling Model, or retrieved via request.getResourceResolver(), request.adaptTo(ResourceResolver.class) or resource.getResourceResolver().

In above case you are not creating new instance of ResourceResolver this is why you do not have to close it explicitly.

However you will have to close ResourceResolver in Sling Model if you will create new instance of it using ResourceResolverFactory.

One remark to your implementation. I would suggest to use specific annotation/injector to get ResourceResolver object. It is also mentioned under Sling documentation

 

// use @SlingObject private ResourceResolver resourceResolver; // instead of @Inject private ResourceResolver resourceResolver;

 

 This is recommended due to performance reasons, more can be found under:

Level 9
January 1, 2023

Thanks @lukasz-m  , glad to know I don’t need to close it , I was sure but wanted to confirm for sling models . Will work towards using slingobject for resource resolver. Do I  have to use slingobject vs inject for custom services written in our case the customExternalizerService? 

when you say “creating” resource resolver is it via the try block or service user accounts ? 

If there is a session leak it should be evident in the logs with the sling model name and unclosed session isn’t it ? 

Also, use of @slingObject , have you used it? Does it lead to troubles like this post ?
https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/open-sessions-jmx/m-p/277967/thread-id/44786

aanchal-sikka
Community Advisor
Community Advisor
January 2, 2023

Hello @nitrohazedev 

 

Q. when you say “creating” resource resolver is it via the try block or service user accounts ? 

A. Please refer to https://cqdump.joerghoh.de/2018/11/14/try-with-resource-or-i-will-never-forget-to-close-a-resource-resolver/ 

If a new resourceresolver has been created explicitly via "resourceResolverFactory" in any way, it should be closed.

 

Q. If there is a session leak it should be evident in the logs with the sling model name and unclosed session isn’t it ? 

A. For analysing unclosed sessions. Please refer to https://helpx.adobe.com/in/experience-manager/kb/AnalyzeUnclosedSessions.html 

https://experienceleague.adobe.com/docs/experience-cloud-kcs/kbarticles/KA-16548.html?lang=en 

 

 

Aanchal Sikka
joerghoh
Adobe Employee
Adobe Employee
January 2, 2023

if you don't explicitly open a ResourceResolver (by using one of the methods of the ResourceResolverFactory) you should not close a ResourceResolver.

See https://cqdump.joerghoh.de/2018/11/12/resourceresolvers-and-sessions-you-open-it-you-close-it/

Level 9
January 2, 2023

@joerghoh 
Does below look ok to you overall wrt resource resolver and rest?
I only open the resource resolver in the custom externalizer class using service user account for additional processing etc

I put the methods in init class so as to avoid method(not init) twice if i just use the getter methods.We have a weird system where old page components may still be in use in terms of inheritance and wcmusepojo as well unfortunately, that is due for updates

 

@Model(adaptables = Resource.class)
public class PageModel{

@Self
private Resource resource;

 

@Inject
@Optional
@Named("image/fileReference")
private String thumbUrl;

 

@OSGiService
private ExternalizerService externalizerService; //custom service injected

@SlingObject
private ResourceResolver resolver;

private String extThumbnailUrl;
private String extPageUrl;


public String getThumbUrl) {
   return thumbUrl;
}

public void setThumbUrl(String thumbUrl){
     this.thumbUrl = thumbUrl;
}

@PostConstruct
protected void init() {
logger.info("in activate method");
if(StringUtils.isNotBlank(thumbUrl)) {
      this.extThumbnailUrl = externalizerService.externalizeUrl(thumbUrl);
}
PageManager pageManager= resolver.adaptTo(PageManager.class);
Page currentPage = pageManager.getContainingPage(resource);
if (externalizerService != null) {
     this.extPageUrl = externalizerService.externalizeUrl(resolver.map(currentPage.getPath())) + ".html";
}

}

public String getExternalizedThumbnailUrl() {
return externalizedThumbnailUrl;
}

public String getExternalizedPageUrl() {
return externalizedPageUrl;
}

}

joerghoh
Adobe Employee
Adobe Employee
January 2, 2023

That java code looks ok from a ResourceResolver perspective. 

 

On a related note, I would just recommend to switch from the @586265 annotation to a more specific one, see https://cqdump.joerghoh.de/2022/11/28/sling-model-performance/