我有一个关于挂毯5.4的问题。我尝试将其与tynamo挂毯安全性和Google App Engine集成在一起,经过一些开发,当应用程序中的“某些内容”不起作用时,我开始遇到这些异常。我写了“东西”,因为问题涉及ExceptionPage(如您在下面所附的stacktrace上看到的)。
有人遇到过这样的问题吗?

当然,我可以发布一些配置文件,但是由于我不知道是什么原因导致此错误页面异常,所以我暂时不摆姿势。

HTTP ERROR 500

Problem accessing /. Reason:

    org.apache.tapestry5.internal.services.RenderQueueException: Render queue error in SetupRender[core/ExceptionReport:loop_0]: Failure reading parameter 'source' of component core/ExceptionReport:loop_0: access denied ("java.lang.RuntimePermission" "modifyThreadGroup") [at classpath:org/apache/tapestry5/corelib/pages/ExceptionReport.tml, line 110]
Caused by:

org.apache.shiro.subject.ExecutionException: org.apache.tapestry5.internal.services.RenderQueueException: Render queue error in SetupRender[core/ExceptionReport:loop_0]: Failure reading parameter 'source' of component core/ExceptionReport:loop_0: access denied ("java.lang.RuntimePermission" "modifyThreadGroup") [at classpath:org/apache/tapestry5/corelib/pages/ExceptionReport.tml, line 110]
    at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:385)
    at org.tynamo.security.services.impl.SecurityConfiguration.service(SecurityConfiguration.java:54)
    at $HttpServletRequestFilter_12a67d391b5c.service(Unknown Source)
    at $HttpServletRequestHandler_12a67d391b5f.service(Unknown Source)
    at org.apache.tapestry5.internal.gzip.GZipFilter.service(GZipFilter.java:59)
    at $HttpServletRequestHandler_12a67d391b5f.service(Unknown Source)
    at org.apache.tapestry5.internal.services.IgnoredPathsFilter.service(IgnoredPathsFilter.java:62)
    at $HttpServletRequestFilter_12a67d391b59.service(Unknown Source)
    at $HttpServletRequestHandler_12a67d391b5f.service(Unknown Source)
    at org.apache.tapestry5.modules.TapestryModule$1.service(TapestryModule.java:804)
    at $HttpServletRequestHandler_12a67d391b5f.service(Unknown Source)
    at $HttpServletRequestHandler_12a67d391b58.service(Unknown Source)
    at org.apache.tapestry5.TapestryFilter.doFilter(TapestryFilter.java:166)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:127)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:366)
    at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:349)
    at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:98)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:503)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

最佳答案

问题不是异常页面,而是Google App Engine(GAE)实施其安全策略以限制产生新线程的方式。该行:

access denied ("java.lang.RuntimePermission" "modifyThreadGroup")


您的堆栈跟踪中的源自Java Security Manager违反了该策略。尽管Tynamo的tapestry-security不调用新线程,但显然不允许在GAE中调用Callable.call()。请参见SecurityConfiguration在绑定当前执行的主题之后如何调用过滤器链。

Callable只是一个接口,因此GAE不必禁止对其进行调用,但是我怀疑,与尝试阻止可能会或可能不会产生线程的各种Executor服务的执行相比,它们更容易做到。

但是,SecurityConfiguration完全不需要使用Callable。 SecurityConfiguration是在Shiro最初的AbstractShiroFilter之后实现的,但是也可以将主题手动绑定到当前正在执行的线程,如下所示:

    ThreadContext.bind(securityManager);
    WebSubject subject = new WebSubject.Builder(securityManager, originalRequest, response).buildWebSubject();
    ThreadContext.bind(subject);
    try {
        // return subject.execute(new Callable<Boolean>() {
        // public Boolean call() throws Exception {
            if (chain == null) return handler.service(request, response);
            else {
                boolean handled = chain.getHandler().service(request, response);
                return handled || handler.service(request, response);
            }
        // }
        // });
    }
    finally {
        ThreadContext.remove(subject);
        ThreadContext.remove();
    }


您可以使用与上述操作方式相同的版本自己覆盖SecurityConfiguration。如果您想提供帮助,请尝试一下,让我知道其他所有操作是否都有效。由于GAE对于成熟的Java应用程序可能是一个相当严格的环境,因此您可能会遇到其他问题。

08-05 21:14