【问题标题】:Jetty+Jersey, unexpected exception: Asynchronous processing not supported on Servlet 2.x containerJetty+Jersey,意外异常:Servlet 2.x 容器不支持异步处理
【发布时间】:2016-04-18 12:09:41
【问题描述】:

我正在开发一个 JAX-RS 服务器,我需要在其中异步向客户端提供答案。我正在以编程方式加载服务器。就我的目的而言,我正在使用 Jetty 和 Jersey 实现。这里有我的相关代码部分:

// 文件:EntryPoint.java

@Path("/explorer")
public class EntryPoint {

@GET
@Path("/{table}")
@Produces(MediaType.APPLICATION_JSON)
public void querySearch( @PathParam     ("table")   String          table, 
                         @QueryParam    ("source")  String          source, 
                         @QueryParam    ("from")    int             startTime, 
                         @QueryParam    ("until")   int             endTime,
                         @Suspended     final       AsyncResponse   asyncResponse) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            String result = veryExpensiveOperation();
            asyncResponse.resume(result);
        }

        private String veryExpensiveOperation() {
            return "{\"Source\":"+source+",\"Table\":\""+table+",\"StartTime\":\""+startTime+",\"EndTime\":\""+endTime+"\"}";
        }
    }).start();
}

// 文件:Service.java

private void startWS(String address, int port) throws Exception, InterruptedException {

    ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
    context.setContextPath("/");

    Server jettyServer = new Server();

    // HTTP connector
    ServerConnector http = new ServerConnector(jettyServer);
    http.setHost(address);
    http.setPort(port);

    jettyServer.addConnector(http);
    jettyServer.setHandler(context);

    ServletHolder jerseyServlet = context.addServlet(
         org.glassfish.jersey.servlet.ServletContainer.class, "/*");
    jerseyServlet.setInitOrder(0);

    // Tells the Jersey Servlet which REST service/class to load.
    jerseyServlet.setInitParameter(
       "jersey.config.server.provider.classnames",
       EntryPoint.class.getCanonicalName());

    try {
        jettyServer.start();
        jettyServer.join();
    } finally {
        jettyServer.destroy();
    }
}

// pom.xml(只有相关的依赖...我把版本放在每个dep中)

    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-server</artifactId>
        <version>9.3.8.v20160314</version>
    </dependency>

    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-servlet</artifactId>
        <version>9.3.8.v20160314</version>
    </dependency>

    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-util</artifactId>
        <version>9.3.8.v20160314</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-server</artifactId>
        <version>2.22.2</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet-core</artifactId>
        <version>2.22.2</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-jetty-http</artifactId>
        <version>2.22.2</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-moxy</artifactId>
        <version>2.22.2</version>
    </dependency>

服务器运行正常,但是,当我尝试调用我的服务时,出现以下异常:

12:39:22:497|3698-00048:WARN [org.eclipse.jetty.server.HttpChannel] - //pisa122:9090/explorer/cm_order?ource=BBG_BOND&from=20160410&until=20160418 Thread {qtp872786524-48}
javax.servlet.ServletException: java.lang.UnsupportedOperationException: Asynchronous processing not supported on Servlet 2.x container.
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:489)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:845)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:583)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:224)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1160)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1092)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
at org.eclipse.jetty.server.Server.handle(Server.java:518)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:308)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:244)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceAndRun(ExecuteProduceConsume.java:246)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:156)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:654)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.UnsupportedOperationException: Asynchronous processing not supported on Servlet 2.x container.
at org.glassfish.jersey.servlet.WebComponent$3.suspend(WebComponent.java:138)
at org.glassfish.jersey.servlet.internal.ResponseWriter.suspend(ResponseWriter.java:125)
at org.glassfish.jersey.server.ServerRuntime$AsyncResponder.suspend(ServerRuntime.java:910)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:327)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
... 24 more

同样的请求,当我同步返回时,没有问题。我还检查了 maven Dependency Hierarchy,确实看到了 servlet-api 的 3.1 版本(请参阅screenshot)。知道我的代码/pom 有什么问题吗?我已经检查了Register ServletContainer programatically in Osgi,但这并没有帮助。谢谢大家! :)

【问题讨论】:

  • 你的 web.xml 是什么?
  • 我的应用程序没有部署在网络服务器中,服务器是从应用程序本身以编程方式运行的

标签: java maven jersey


【解决方案1】:

您需要以下 servlet 3.x 支持

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>2.22.2</version>
</dependency>

【讨论】:

  • 非常感谢,这解决了问题。现在我想知道哪个依赖项导入了错误版本的 servlet API,或者,我只能假设记录的错误消息具有误导性……无论如何,再次感谢 :)
  • 不是你引入了旧版本,只是上面的依赖是3.x支持所必需的。缺少它只是假设您正在运行一个较旧的容器,即使您不是。我猜这个错误可能有点误导
猜你喜欢
  • 2014-09-17
  • 2017-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-19
  • 1970-01-01
  • 2015-08-13
  • 2012-10-06
相关资源
最近更新 更多