"Unclosed ResourceResolver was created here"

Introduction
We often create a "ResourceResolver" object to obtain the Session Object or access the JCR Content, etc. Many times, we create a Resource Resolver object and forget to close it, which causes problems with the AEM Server. When checking the logs, you will find the following Warning statements: Unclosed ResourceResolver was created here.
Issue # 1:
AEM Logs are logging the WARN statements “Unclosed ResourceResolver was created here”. This will be found in the error.log file.
Solution:
- Obtain the Resource Resolver object in the “try” block and ensure to close it in the “finally” block. Closing in the “finally” block will ensure that the Resource Resolver will be closed even in case of any exception.
private void doSomething() {
ResourceResolverFactory resolverFactory;
ResourceResolver resourceResolver = null;
try {
Map <String, Object> param = new HashMap <> ();
param.put(ResourceResolverFactory.SUBSERVICE,
"myServiceUser");
resourceResolver = resolverFactory.getServiceResourceResolver(param);
// Business Logic goes here
} catch (Exception e) {
// Handle Exception gracefully
} finally {
if (null != resourceResolver && resourceResolver.isLive()) {
resourceResolver.close();
}
}
}
Create Resource Resolver Object with “try-with-resources statement“.
If the resource implements
java.lang.AutoCloseable
, the try-with-resources statement ensures that each resource is closed at the end of the statement.
ResourceResolverFactory resolverFactory;
try (ResourceResolver resolver = resolverFactory.getServiceResourceResolver(Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, "myServiceUser"))) {
// Business Logic goes here
}
Despite following the above, the WARN statements “Unclosed ResourceResolver was created here” were still reported in the logs. This brings us to the next issue.
Issue # 2:
Upon analysis, we determined that the issue arose when executing the JCR queries using the Query Builder from the code.
Solution:
Whenever the results are retrieved after executing the query, a resource resolver is opened, and it is crucial to ensure that it is properly closed, as shown in the code snippet below.
// Create an Object for Resource Resolver for Query Builder Resource Resolver
ResourceResolver queryBuilderResourceResolver = null;
try {
Query query = createQuery(); // Create query
SearchResult searchResult = query.getResult(); // Execute query
List <Hit> hits = searchResult.getHits();
for (Hit hit: hits) {
if (queryBuilderResourceResolver == null) {
// Get a reference to Query Builder's leaking Resource Resolver
queryBuilderResourceResolver = hit.getResource().getResourceResolver();
}
// Business Logic goes here
}
} catch (Exception e) {
//handle exception gracefully
} finally {
if (queryBuilderResourceResolver != null) {
// Always close the resourceResolver.
queryBuilderResourceResolver.close();
}
}
The above finally helped in resolving the Unclosed Resource Resolver issue. Hope this will help other AEM developers.
Bonus Tip:
Create a custom index for the custom query that has to be executed from the code. This will ensure quick response times for the queries.
Please leave a comment if you're still experiencing the issue and need assistance, or if you have any suggestions. Don't hesitate to reach out to me if you need help troubleshooting the problem.
Subscribe to my newsletter
Read articles from Nitish Jain directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Nitish Jain
Nitish Jain
Nitish Jain is a seasoned Adobe AEM/CQ developer and architect with deep expertise in crafting connected digital experiences using the AEM technology stack. He has led the implementation of numerous large-scale AEM solutions across diverse industries, adhering to best practices and delivering scalable, high-performance architectures.