ContainerRequestContext的独立Jersey Concurrent Invocations#abortWith(..)Hang Server

时间:2015-07-09 19:17:43

标签: java concurrency jersey-2.0

我有一个JAX-RS过滤器使用ContainerRequestContext#abortWith(..)来表示授权失败:

@Priority(Priorities.AUTHORIZATION)
public class RequirePrincipalFilter implements ContainerRequestFilter {

    private static final Logger LOG = LoggerFactory
            .getLogger(RequirePrincipalFilter.class);

    @Override
    public void filter(final ContainerRequestContext requestContext)
            throws IOException {
        if (requestContext.getSecurityContext() == null
                || requestContext.getSecurityContext().getUserPrincipal() == null) {
            LOG.debug("No Principal");
            requestContext.abortWith(Response
                    .status(Status.UNAUTHORIZED)
                    .entity(new ErrorRepresentation(Status.UNAUTHORIZED
                            .getStatusCode(), "Authorization required"))
                    .header("WWW-Authenticate", "Bearer").build());
            LOG.debug("Request Aborted");
        }
    }
}

当连续发出请求以便调用abortWith(..)时, 没有问题。但是,当发出两个或更多这样的请求时 同时,服务发散,使得不返回响应 和 连接挂起。对服务器的任何进一步请求 善良 - 通过过滤器授权,未经授权,甚至是请求 完全绕过过滤器 - 也导致挂起连接而没有响应。

为所有适用的abortWith(..)调用两个日志语句 调用。即代码未挂起在方法调用上 本身。

我的问题是:我正确使用abortWith(..)设施吗? 我怀疑我自己的错误 - 否则我希望有 发现有人遇到这个麻烦。

我在Grizzly2 HTTP容器中使用Jersey 2.17运行它,JVM是 Oracle JSE 1.8.0_45。我也尝试用JDK容器替换Grizzly容器。问题是一样的。

作为一项实验,我尝试将调用序列化为abortWith(..) 通过使用静态LOG作为监视器从同步块内调用它。即使调用序列化,问题仍然存在。

0 个答案:

没有答案