We have created a custom Utility class with two functions:
1. getResourceResolver()
2. closeResourceResolver()
Whereever we need to get an object of resource reolver, we call the "getResourceResolver" function inside "try" block and in "finally" block, we call the "closeResourceResolver" function.
Recently, the AEM has started logging the "INFO" in error.logs stating "Unclosed ResourceResolver was created here:" for "getResourceResolver()" function for line "resolverFactory.getServiceResourceResolver" line. We cannot close the Resource Resolver in the same function as this function objective is to create and return the resource resolver object.
Please advise.
- Thanks
Solved! Go to Solution.
Topics help categorize Community content and increase your ability to discover relevant content.
Views
Replies
Total Likes
You get this message only if you forgot to close the ResourceResolver; that means that in some area of your code you open it but forgot to close it.
1. ResourceResolver Creation: The getResourceResolver() function should only handle the creation and return of the ResourceResolver.
2. Closing ResourceResolver: You cannot close the ResourceResolver inside getResourceResolver() because the calling code will need to use it. Instead, close it in the calling code in a finally block, ensuring it's properly cleaned up.
Refactor Example:
1. Utility Class (ResourceResolverUtility): The utility class should only return the ResourceResolver, and another method should handle its closing.
public class ResourceResolverUtility {
public static ResourceResolver getResourceResolver() {
return resolverFactory.getServiceResourceResolver(null); // Adjust with necessary config
}
public static void closeResourceResolver(ResourceResolver resolver) {
if (resolver != null && resolver.isLive()) {
resolver.close();
}
}
}
2. Calling Code: In the code where you use the getResourceResolver(), close it in the finally block to ensure it is always closed, even if an exception occurs.
ResourceResolver resolver = null;
try {
resolver = ResourceResolverUtility.getResourceResolver();
// Do your work here
} catch (Exception e) {
// Handle exceptions
} finally {
if (resolver != null) {
ResourceResolverUtility.closeResourceResolver(resolver);
}
}
Hi @AmitVishwakarma ,
This is exactly we aredoing currently and getting the "Unclosed ResourceResolver was created here" error on logs for the utility class where the resourceresolver object is created.
Views
Replies
Total Likes
Hi @nitish-jain
the best practices recommend not to use it like this and always fetch the resourceresolver with try-with-resources statement in Java as it is used to automatically close resources that implement the AutoCloseable or Closeable interfaces.
best way to main a common user is to define the Map at a utility level and then call that map everywhere like below
public static final Map<String, Object> READ_WRITE_SERVICE_USER_MAP = Collections
.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object) "userservice");
Example:
try(ResourceResolver resourceResolver = resourceResolverFactory.getServiceResourceResolver(ProjectConstant.READ_WRITE_SERVICE_USER_MAP)){
// code
}
Thank @chaudharynick,
I am now doing this way to avoid getting the error but this duplicates the resource resolver object creation code across the files.
Views
Replies
Total Likes
Hi @nitish-jain ,
You need to handle the code in such way to create a object once in a flow and pass it via methods only. this will ensure that multiple resolvers are not invoked for functionality and will remove the resource leakage.
best way would be to create a resolver at the origin(service origin method or models) and avoid creating any new resolvers in utils or elsewhere.
You get this message only if you forgot to close the ResourceResolver; that means that in some area of your code you open it but forgot to close it.
Views
Likes
Replies
Views
Likes
Replies