You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@sling.apache.org by "Alexander Klimetschek (JIRA)" <ji...@apache.org> on 2015/01/14 03:59:34 UTC

[jira] [Comment Edited] (SLING-4301) Support user.jcr.session.logout option for the jcr resource provider

    [ https://issues.apache.org/jira/browse/SLING-4301?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14276415#comment-14276415 ] 

Alexander Klimetschek edited comment on SLING-4301 at 1/14/15 2:59 AM:
-----------------------------------------------------------------------

Attached a quick patch [^SLING-4301.patch].

But there is a problem, at least when used with servlets that directly register with the osgi HttpService: the session gets closed before the HttpServlet.service() method is called, thus code that gets the resource resolver from the request attributes will get "session already closed" exceptions. (This case does not use sling servlets at the moment, but it uses the sling authenticator in handleSecurity).

This is weird, below are 2 stack traces illustrating this. Note the bottom part below ServletHolder.java:684 are exactly the same for both, so I left them out.

1. session getting closed too early:
{code}
	at org.apache.sling.jcr.resource.internal.helper.jcr.RepositoryHolder.release(RepositoryHolder.java:52)
	at org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProvider.close(JcrResourceProvider.java:246)
	at org.apache.sling.resourceresolver.impl.helper.ResourceResolverContext.close(ResourceResolverContext.java:140)
	at org.apache.sling.resourceresolver.impl.ResourceResolverImpl.close(ResourceResolverImpl.java:144)
	at org.apache.sling.auth.core.impl.SlingAuthenticator.requestDestroyed(SlingAuthenticator.java:626)
	at org.apache.felix.http.base.internal.listener.ServletRequestListenerManager.requestDestroyed(ServletRequestListenerManager.java:46)
	at org.apache.felix.http.base.internal.DispatcherServlet.service(DispatcherServlet.java:71)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
{code}

2. servlet runs, tries to access session
{code}
java.lang.IllegalStateException: This session has been closed
	at com.google.common.base.Preconditions.checkState(Preconditions.java:150)
	at org.apache.jackrabbit.oak.core.ContentSessionImpl.checkLive(ContentSessionImpl.java:85)
	at org.apache.jackrabbit.oak.core.MutableRoot.checkLive(MutableRoot.java:172)
	at org.apache.jackrabbit.oak.core.MutableRoot.getQueryEngine(MutableRoot.java:301)
	at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.getQueryEngine(SessionDelegate.java:557)
	at org.apache.jackrabbit.oak.jcr.query.QueryManagerImpl.<init>(QueryManagerImpl.java:69)
	at org.apache.jackrabbit.oak.jcr.session.WorkspaceImpl.<init>(WorkspaceImpl.java:76)
	at org.apache.jackrabbit.oak.jcr.session.SessionContext.createWorkspace(SessionContext.java:173)
	at org.apache.jackrabbit.oak.jcr.session.SessionContext.getWorkspace(SessionContext.java:149)
	at org.apache.jackrabbit.oak.jcr.session.SessionImpl.getWorkspace(SessionImpl.java:279)
	at sun.reflect.GeneratedMethodAccessor21.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.apache.sling.jcr.base.SessionProxyHandler$SessionProxyInvocationHandler.invoke(SessionProxyHandler.java:113)
	at com.sun.proxy.$Proxy4.getWorkspace(Unknown Source)
	at com.adobe.cq.creativecloud.filesync.DesktopSyncServlet.service(DesktopSyncServlet.java:142)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at org.apache.felix.http.base.internal.handler.ServletHandler.doHandle(ServletHandler.java:339)
	at org.apache.felix.http.base.internal.handler.ServletHandler.handle(ServletHandler.java:300)
	at org.apache.felix.http.base.internal.dispatch.ServletPipeline.handle(ServletPipeline.java:93)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:50)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at org.apache.sling.i18n.impl.I18NFilter.doFilter(I18NFilter.java:129)
	at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at com.adobe.granite.license.impl.LicenseCheckFilter.doFilter(LicenseCheckFilter.java:300)
	at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at org.apache.felix.http.sslfilter.internal.SslFilter.doFilter(SslFilter.java:89)
	at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at com.adobe.granite.commons.httplogfilter.HttpLogFilter.doFilter(HttpLogFilter.java:79)
	at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at org.apache.sling.security.impl.ReferrerFilter.doFilter(ReferrerFilter.java:290)
	at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at org.apache.sling.featureflags.impl.FeatureManager.doFilter(FeatureManager.java:115)
	at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at org.apache.sling.engine.impl.log.RequestLoggerFilter.doFilter(RequestLoggerFilter.java:75)
	at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at org.apache.felix.http.base.internal.dispatch.FilterPipeline.dispatch(FilterPipeline.java:76)
	at org.apache.felix.http.base.internal.dispatch.Dispatcher.dispatch(Dispatcher.java:49)
	at org.apache.felix.http.base.internal.DispatcherServlet.service(DispatcherServlet.java:67)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
{code}

The DesktopSyncServlet looks like this:
{code}
public class DesktopSyncServlet extends HttpServlet {

    @Activate
    private void setup(ComponentContext ctx) throws ServletException, NamespaceException {

        httpService.registerServlet("/mypath", this, null, new HttpContext() {

            public boolean handleSecurity(HttpServletRequest req, HttpServletResponse res) throws IOException {
                if (authenticationSupport != null) {
                    return authenticationSupport.handleSecurity(req, res);
                }
                return false;
            }
            
            ...
        });
    }
    
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
            
        ResourceResolver resolver = (ResourceResolver) req.getAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER);
        Session session = resolver.adaptTo(Session.class);
        
        session.getWorkspace(); // throws because session is already closed
        
    }
}
{code}


was (Author: alexander.klimetschek):
Attached a quick patch [^SLING-4301.patch].

But there is a problem, at least when used with servlets that directly register with the osgi HttpService: the session gets closed before the HttpServlet.service() method is called, thus code that gets the resource resolver from the request attributes will get "session already closed" exceptions. (This case does not use sling servlets at the moment, but it uses the sling authenticator in handleSecurity).

This is weird, below are 2 stack traces illustrating this. Note the bottom part below ServletHolder.java:684 are exactly the same for both, so I left them out.

1. session getting closed too early:
{code}
	at org.apache.sling.jcr.resource.internal.helper.jcr.RepositoryHolder.release(RepositoryHolder.java:52)
	at org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProvider.close(JcrResourceProvider.java:246)
	at org.apache.sling.resourceresolver.impl.helper.ResourceResolverContext.close(ResourceResolverContext.java:140)
	at org.apache.sling.resourceresolver.impl.ResourceResolverImpl.close(ResourceResolverImpl.java:144)
	at org.apache.sling.auth.core.impl.SlingAuthenticator.requestDestroyed(SlingAuthenticator.java:626)
	at org.apache.felix.http.base.internal.listener.ServletRequestListenerManager.requestDestroyed(ServletRequestListenerManager.java:46)
	at org.apache.felix.http.base.internal.DispatcherServlet.service(DispatcherServlet.java:71)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
{code}

2. servlet runs, tries to access session
{code}
java.lang.IllegalStateException: This session has been closed
	at com.google.common.base.Preconditions.checkState(Preconditions.java:150)
	at org.apache.jackrabbit.oak.core.ContentSessionImpl.checkLive(ContentSessionImpl.java:85)
	at org.apache.jackrabbit.oak.core.MutableRoot.checkLive(MutableRoot.java:172)
	at org.apache.jackrabbit.oak.core.MutableRoot.getQueryEngine(MutableRoot.java:301)
	at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.getQueryEngine(SessionDelegate.java:557)
	at org.apache.jackrabbit.oak.jcr.query.QueryManagerImpl.<init>(QueryManagerImpl.java:69)
	at org.apache.jackrabbit.oak.jcr.session.WorkspaceImpl.<init>(WorkspaceImpl.java:76)
	at org.apache.jackrabbit.oak.jcr.session.SessionContext.createWorkspace(SessionContext.java:173)
	at org.apache.jackrabbit.oak.jcr.session.SessionContext.getWorkspace(SessionContext.java:149)
	at org.apache.jackrabbit.oak.jcr.session.SessionImpl.getWorkspace(SessionImpl.java:279)
	at sun.reflect.GeneratedMethodAccessor21.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.apache.sling.jcr.base.SessionProxyHandler$SessionProxyInvocationHandler.invoke(SessionProxyHandler.java:113)
	at com.sun.proxy.$Proxy4.getWorkspace(Unknown Source)
	at com.adobe.cq.creativecloud.filesync.DesktopSyncServlet.service(DesktopSyncServlet.java:142)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at org.apache.felix.http.base.internal.handler.ServletHandler.doHandle(ServletHandler.java:339)
	at org.apache.felix.http.base.internal.handler.ServletHandler.handle(ServletHandler.java:300)
	at org.apache.felix.http.base.internal.dispatch.ServletPipeline.handle(ServletPipeline.java:93)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:50)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at org.apache.sling.i18n.impl.I18NFilter.doFilter(I18NFilter.java:129)
	at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at com.adobe.granite.license.impl.LicenseCheckFilter.doFilter(LicenseCheckFilter.java:300)
	at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at org.apache.felix.http.sslfilter.internal.SslFilter.doFilter(SslFilter.java:89)
	at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at com.adobe.granite.commons.httplogfilter.HttpLogFilter.doFilter(HttpLogFilter.java:79)
	at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at org.apache.sling.security.impl.ReferrerFilter.doFilter(ReferrerFilter.java:290)
	at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at org.apache.sling.featureflags.impl.FeatureManager.doFilter(FeatureManager.java:115)
	at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at org.apache.sling.engine.impl.log.RequestLoggerFilter.doFilter(RequestLoggerFilter.java:75)
	at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
	at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
	at org.apache.felix.http.base.internal.dispatch.FilterPipeline.dispatch(FilterPipeline.java:76)
	at org.apache.felix.http.base.internal.dispatch.Dispatcher.dispatch(Dispatcher.java:49)
	at org.apache.felix.http.base.internal.DispatcherServlet.service(DispatcherServlet.java:67)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
{code}

> Support user.jcr.session.logout option for the jcr resource provider
> --------------------------------------------------------------------
>
>                 Key: SLING-4301
>                 URL: https://issues.apache.org/jira/browse/SLING-4301
>             Project: Sling
>          Issue Type: Improvement
>          Components: JCR
>            Reporter: Alexander Klimetschek
>         Attachments: SLING-4301.patch
>
>
> Add a new AuthenticationInfo option {{user.jcr.session.logout}} that if set to true would automatically close the session passed via {{user.jcr.session}} at the end of the request.
> Purpose: As discussed on the [list|http://sling.markmail.org/thread/ceshw42z63r4bu7i], when using [user.jcr.session|http://sling.apache.org/apidocs/sling6/org/apache/sling/jcr/resource/JcrResourceConstants.html#AUTHENTICATION_INFO_SESSION] to pass a session created by an AuthenticationHandler itself, this is currently never closed (since the original use case for it comes from somewhere else where this wasn't required). The only way to use it from an AuthenticationHandler is to also implement a ServletFilter that tracks it and closes the session "manually" at the end of the request, which is bad since this would create another servlet filter for each authentication handler that wishes to use this.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)