Sling - Who is closing my JCR Session?


Has this happened to you? - You got the JCR session, but at times, you find that "someone" closed the JCR session! And that too - its very inconsistent. Sometimes it works and other times it does not! Well then its that you have hit the Sling / CQ development anti-pattern. And possibly this is what you see in your log:

javax.jcr.RepositoryException: This session has been closed.

As suggested by Jorg Hoh on his blog on CQ development patterns, you should rely on Sling objects as much as possible, rather than relying directly on the JCR objects. But at those cases (e.g. writing to a repository) when you will have to directly rely on the JCR repository you will have to still use the JCR Session, its recommended that you directly get the JCR session from the Sling repository, and not adapt it from the ResourceResolver, IF you do not intend to use the ResourceResolver directly.

private ResourceResolverFactory resolverFactory;

// Wrong way of obtaining JCR Session
private Session getSessionAntipattern() throws LoginException {
 ResourceResolver resolver = resolverFactory.getServiceResourceResolver(null);
 return resolver.adaptTo(Session.class);
Code Listing 1: JCR Session Creation Antipattern

private SlingRepository slingRepository;

// Correct way of obtaining JCR session
private Session getJCRSession() throws RepositoryException {
 return slingRepository.loginService(null, null);
Code Listing 2: JCR Session Creation Pattern

You may wonder, what's wrong. Logically thinking, why would you retrieve the ResourceResolver (and  adapt it to JCR Session), if you do not intend to use the ResourceResolver?  This logic has made the Sling developer's to close the underlying JCR Session of the ResourceResolver when the ResourceResolver object is Garbage Collected. Although, how this is done is being changed across the releases, the basic idea of releasing the resources held up (JCR Session) is still valid.

If you observe in the code snippet 1 (antipattern), the scope of the ResourceResolver object ends as soon as the method returns, which makes it eligible for garbage collection. This means that whenever the garbage collector runs, the JCR Session got through the antipattern would be closed - oops! This explains your JCR Session getting closed inconsistently.

I would like to emphasize that adapting to JCR Session from ResourceResolver itself is not wrong, if you intend to use the ResourceResolver along, other than just adapting it to JCR Session.

Hope this post helps someone save some time debugging on the JCR Session getting closed inconsistently.

blog comments powered by Disqus