- Published on
AEM Best Practices - When to Close Your ResourceResolver and When Not To
- Authors
- Name
- Khalil
- @Im_Khalil
If you're an AEM developer, you've definitely used a ResourceResolver
. It's a key tool that lets you find, read, and change content in the AEM repository.
But there’s a simple rule about using it that many developers overlook — and it can cause big problems for your website:
Close the resolver if you opened it. Don’t close it if AEM gave it to you.
Ignoring this rule can lead to resource leaks, which are a common cause of performance issues and even server crashes in AEM.
So, how do you know if you need to close a ResourceResolver?
The answer depends on how you got it in the first place.
When You MUST Close It
If you are using a Java OSGi service or a background task, you will create a new ResourceResolver using the ResourceResolverFactory.
This creates a fresh connection to the repository. If you don't close this connection, it stays open and takes up system resources.
Imagine leaving a faucet running — eventually, you'll flood the room.
The best way to close it is with a try-with-resources block.
This is a special Java feature that automatically closes the resolver for you, even if an error happens.
The Modern, Recommended Way (Use This)
try (ResourceResolver resolver = resolverFactory.getServiceResourceResolver(null)) {
// Your code here
} catch (Exception e) {
// Handle error
}
// The resolver is automatically closed here
⚠️ Use code with caution.
When You MUST NOT Close It
What if you're writing code for a component or a servlet that handles a web request?
In this case, AEM gives you a ResourceResolver that is tied to that specific request.
Think of it like being handed a car key by a valet at a fancy party.
You use the car, and when you're done, you hand the keys back to the valet.
The valet handles the rest.
In AEM, the Sling framework is the valet.
It handles the whole request and will close the ResourceResolver for you at the end.
If you try to close a request-based resolver, you will cause a major error.
Any other components or services that run later in the same request will find a closed resolver and crash.
So, if you get your ResourceResolver
from one of these places, do NOT close it:
From a servlet request:
slingRequest.getResourceResolver()
Inside a Sling Model or a component (e.g., via injection)
By adapting an existing resource:
resource.adaptTo(ResourceResolver.class)
What Happens When Things Go Wrong?
1. If You Don’t Close a Factory-Created Resolver (A Leak)
Performance Degradation:
Each open resolver consumes memory and system resources.
Over time, an accumulation of unclosed resolvers will cause AEM to slow down.
System Instability:
If the leaks are bad enough, they can cause an OutOfMemoryError
and crash the AEM instance.
AEM has a built-in mechanism to warn you about unclosed resolvers.
What to Look for in the Logs
Unclosed ResourceResolver was created here:
org.apache.sling.api.resource.ResourceResolverFactory.getServiceResourceResolver(ResourceResolverFactory.java:...)
...
You will see this warning repeatedly, often followed by a stack trace pointing to the exact line of code that created the leaky resolver.
If you see this, it’s a clear signal to fix your code.
2. If You Try to Close a Request-Based Resolver (Manual-Close Error)
Unexpected Exceptions:
Other parts of the code processing the same request will suddenly find their resolver closed.
This will immediately throw an IllegalStateException
.
Page Rendering Failures:
This typically causes a major error on the page where the code is executing, and the component will fail to render properly.
What to Look for in the Logs
java.lang.IllegalStateException: This resource resolver has already been closed.
at org.apache.sling.resourceresolver.impl.ResourceResolverImpl.checkLive(ResourceResolverImpl.java:...)
...
The stack trace will show a call to a resolver method (getResource
, map
, etc.) that fails because the resolver was already shut down.
You should trace the stack to see which component or service mistakenly closed the resolver prematurely.
A Simple Test to Remember the Rule
If you're ever unsure whether to close your resolver, just ask yourself this question:
"Did I get this resolver from the ResourceResolverFactory?"
If the answer is yes, the resolver was opened and must be closed. Use try-with-resources for safety.
If the answer is no, AEM opened it (e.g., from the
SlingHttpServletRequest
), and AEM will handle closing it.
Final Thoughts
AEM developers often underestimate how easy it is to cause performance issues by mishandling ResourceResolver
.
By simply following this one rule — close it if you opened it; don’t if AEM gave it to you — you’ll prevent leaks, improve stability, and ensure smooth performance in your AEM environment.