Closing ResourceResolver and Session | Community
Skip to main content
Level 3
January 5, 2016
Solved

Closing ResourceResolver and Session

  • January 5, 2016
  • 15 replies
  • 21767 views

Hi All,

In order to avoid the below error, I am creating resourceresolver and session at every place(all methods) and closing it at the end of method in finally block.. Sample piece of code for creating and closing resourceresolver and session in single method

I am doing lot of operations(remove node, add/modify/delete property under the node) in 30 different methods. Whether it will cause any performance issue if we creating and closing resourceresolver and session at 30 methods. 

Error:

01.01.2016 09:21:56.916 *WARN* [0:0:0:0:0:0:0:1 [1424679716845] GET /content/geometrixx/en/services.html HTTP/1.0] org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate Attempt to perform hasProperty while another thread is concurrently reading from session-494. Blocking until the other thread is finished using this session. Please review your code to avoid concurrent use of a session.

java.lang.Exception: Stack trace of concurrent access to session-494

at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.perform(SessionDelegate.java:276)

at org.apache.jackrabbit.oak.jcr.session.ItemImpl.perform(ItemImpl.java:113)

at org.apache.jackrabbit.oak.jcr.session.NodeImpl.hasProperty(NodeImpl.java:812)

at org.apache.sling.jcr.resource.JcrPropertyMap.read(JcrPropertyMap.java:350)

 

Sample piece of code :

ResourceResolver resolver = null;
Session session = null;

        try {

            resolver = resolverFactory.getServiceResourceResolver(null);

            session = resolver.adaptTo(Session.class);

            Node test= session.getNode("/content/dam");

           updateproperty(test);

            session.save();

            }

        } catch (Exception e) {

            Logging exception

        } finally {

            if (session != null && session.isLive()) {

                session.logout();

            }

        if (resolver != null && resolver.isLive()) {

            resolver.close();

        }

        }

Best answer by Shashi_Mulugu

Please follow below post for best use of resource resolver

 

https://cqdump.wordpress.com/2018/11/14/try-with-resource-or-i-will-never-forget-to-close-a-resource-resolver/

15 replies

Lokesh_Shivalingaiah
Level 10
January 7, 2016

Technically you can do that but ideally, you should declare it globally for the service which can be used to complete a flow or a transaction and then make your master method to have the finally block to close the session or resourceresolver.

If you have multiple method which works independently, then you can still have the local variables

joerghoh
Adobe Employee
Adobe Employee
January 7, 2016

sankarr26533925 wrote...

Can I create resourceresolver in local method and close it ?

 

That's perfectly possible.

Jitendra_S_Toma
Level 10
January 8, 2016

@sankarr26533925,

I don't think that could solve your problem. But you can try it. I think, at the job level, Open resourceResolver & close it, but make sure it is in a synchronized block.

Jitendra

Shashi_Mulugu
Community Advisor
Shashi_MuluguCommunity AdvisorAccepted solution
Community Advisor
June 2, 2020
January 3, 2025

Creating and closing ResourceResolver and Session in multiple methods can lead to potential performance issues, especially when used in high-frequency operations or with heavy resource-intensive tasks. However, it can also help in avoiding session contention issues like the one described. Below are recommendations to address your concerns and improve your implementation:

Key Recommendations

  1. Reuse ResourceResolver and Session Where Possible:

    • If your operations are scoped to a single thread and have a consistent context, consider reusing the same ResourceResolver and Session across multiple methods within the same operation.

    • Use a higher-level object to manage and share these resources, such as a service or utility class.

  2. Thread-Safe Practices:

    • Avoid sharing Session or ResourceResolver instances across threads.

    • Each thread should have its own instance to prevent concurrent access issues.

  3. Batch Operations:

    • Instead of performing operations like adding, modifying, or deleting properties across 30 methods individually, batch these operations when possible. For example, collect changes and apply them in a single session save.

    • This reduces the overhead of repeatedly opening and closing sessions.

  4. Exception Handling:

    • Ensure robust exception handling within your try-catch block to handle errors gracefully without leaving resources unclosed.

  5. Performance Profiling:

    • Profile your application using tools like JProfiler or VisualVM to monitor session creation, thread contention, and other potential bottlenecks.

  6. Centralized Resource Management:

    • Create a utility method or class to handle ResourceResolver and Session creation and closure, ensuring consistency and reducing code duplication.

Optimized Code Sample

Here’s an updated version of your code that incorporates these suggestions:

java

Copy code

public class ResourceHandler { private final ResourceResolverFactory resolverFactory; public ResourceHandler(ResourceResolverFactory resolverFactory) { this.resolverFactory = resolverFactory; } public void performOperations() { try (ResourceResolver resolver = resolverFactory.getServiceResourceResolver(null)) { Session session = resolver.adaptTo(Session.class); if (session != null) { try { Node test = session.getNode("/content/dam"); updateProperties(test); session.save(); } catch (Exception e) { // Log exception e.printStackTrace(); } } } catch (LoginException e) { // Log exception e.printStackTrace(); } } private void updateProperties(Node node) throws RepositoryException { // Perform your operations here } }

Explanation of Changes

  1. Try-with-Resources:

    • Use try-with-resources for automatic closure of the ResourceResolver. It ensures proper cleanup of resources without needing explicit finally blocks.

  2. Session Reuse:

    • The session is adapted from the ResourceResolver and is used within the same scope, ensuring no shared or stale sessions.

  3. Utility Class:

    • Encapsulate the logic in a reusable handler class to promote better organization and reuse.