Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to AbstractApplicationEventMulticaster in 3.2.9 break HttpSessionEventPublisher in Google AppEngine Runtime [SPR-12002] #16618

Closed
spring-projects-issues opened this issue Jul 16, 2014 · 4 comments
Assignees
Labels
in: core status: backported type: bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Jul 16, 2014

David Fuelling opened SPR-12002 and commented

My Error


I have a Spring webapp running in Google App Engine (GAE). It has been running fine for more than a year, but once I upgraded to Spring 3.2.9.RELEASE, I started getting java.security.AccessControlException's (see stack trace below) when running the app in the AppEngine runtime (Note: the app works fine locally in the AppEngine devserver, which is basically a Jetty container). This is typical for appengine - the runtime classloader permissions are more restrictive in the production runtime than in the development server.

Cause


My app has an HttpSessionEventPublisher configured to publish session events. It appears that #16229 introduced subtle changes to AbstractApplicationEventMulticaster (e1602f7#diff-2047c68c136729519797ac17b17a5bcc) on line 178 that start accessing the classloader of each event's "source" and "type". From my own investigation, it appears that while using SpringSocial (Facebook), the ProviderSignInUtils kicks off a new session, and when the AbstractApplicationEventMulticaster encounters this event, it attempts to get the ClassLoader for the following class, which is not allowed in Appengine: com.google.apphosting.runtime.jetty.SessionManager$AppEngineSession (throws the AccessControlException).

I realize this is somewhat of an AppEngine issue, but am wondering if it makes sense for Spring to try and do something more appropriate here? As-is, anyone using HttpSessions with HttpSessionEventPublisher in AppEngine will probably break.

Here's the stack trace:


org.springframework.social.connect.web.ProviderSignInController signIn: Exception while building authorization URL:
java.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader)
at com.google.appengine.runtime.Request.process-b35531ed0170125f(Request.java)
at java.lang.Class.getClassLoader(Class.java:445)
at org.springframework.util.ClassUtils.isCacheSafe(ClassUtils.java:400)
at org.springframework.context.event.AbstractApplicationEventMulticaster.getApplicationListeners(AbstractApplicationEventMulticaster.java:178)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:86)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:334)
at org.springframework.security.web.session.HttpSessionEventPublisher.sessionCreated(HttpSessionEventPublisher.java:69)
at org.mortbay.jetty.servlet.AbstractSessionManager.addSession(AbstractSessionManager.java:577)
at org.mortbay.jetty.servlet.AbstractSessionManager.newHttpSession(AbstractSessionManager.java:415)
at org.mortbay.jetty.Request.getSession(Request.java:1242)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)
at org.springframework.web.context.request.ServletRequestAttributes.getSession(ServletRequestAttributes.java:79)
at org.springframework.web.context.request.ServletRequestAttributes.setAttribute(ServletRequestAttributes.java:127)
at org.springframework.social.connect.web.HttpSessionSessionStrategy.setAttribute(HttpSessionSessionStrategy.java:8)
at org.springframework.social.connect.web.ConnectSupport.buildOAuth2Url(ConnectSupport.java:223)
at org.springframework.social.connect.web.ConnectSupport.buildOAuthUrl(ConnectSupport.java:128)
at org.springframework.social.connect.web.ProviderSignInController.signIn(ProviderSignInController.java:175)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:45)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:685)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:919)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:851)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)


Affects: 3.2.9, 4.0.2

Reference URL: e1602f7#diff-2047c68c136729519797ac17b17a5bcc

Issue Links:

  • #16229 AbstractApplicationEventMulticaster can leak classes

Backported to: 3.2.11

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jul 16, 2014

David Fuelling commented

For reference, I encountered this issue after thinking it had something todo with SOCIAL-314. In actuality, it appears to be caused by #16229. Also, see here for the AppEngine issue to determine if this is a bug in the appengine runtime: https://code.google.com/p/googleappengine/issues/detail?id=11121&thanks=11121&ts=1405526676

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jul 16, 2014

Juergen Hoeller commented

We could be more defensive there in our rather commonly used ClassUtils.isCacheSafe, catching AccessControlException... Although I find it pretty harsh for a runtime environment to throw that on Class.getClassLoader()!

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jul 16, 2014

Juergen Hoeller commented

We're defensively catching SecurityException now, considering the class cache-safe in that case since it's likely to come from the system class loader.

Committed to master (4.1 RC1); to be backported to 4.0.7 and 3.2.11.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jul 20, 2014

David Fuelling commented

That's great, thanks for looking into this for me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core status: backported type: bug
Projects
None yet
Development

No branches or pull requests

2 participants