簡體   English   中英

使用Swagger文檔的異步jersey REST API中的NullPointerException

[英]NullPointerException in asynchronous jersey REST API that uses Swagger documentation

我正在使用屬於Jersey 2.10應用程序的REST API,它具有一個異步(長輪詢)端點,以及其他幾個CRUD操作的正常同步端點。

例如,異步服務如下所示:

@GET
@Path("poll/{groupId}")
@ManagedAsync
public void poll(@Suspended final AsyncResponse asyncResponse, @NotNull @PathParam("groupId") Integer groupId) {
    asyncResponse.setTimeout(SERVICE_TIMEOUT, TimeUnit.SECONDS);

    List<User> users= Collections.emptyList();

    while (users.isEmpty() && asyncResponse.isSuspended()) {
        users= userService.findUsersByGroupId(groupId);

        if (users.isEmpty()) {
            try {
                Thread.sleep(POLL_INTERVAL);
            } catch (InterruptedException ex) {}
        }
    }

    asyncResponse.resume(users.toArray(new TestView[0]));
}   

過去一切正常運行,異步請求在jersey管理的線程池上的自己線程中處理。 並且同步服務按預期工作。

但是有一天我向團隊建議添加一個文檔工具,Swagger是一個非常性感的工具,因此我們安裝了一些文檔,並將其添加到同步服務中。

噩夢開始后,我們的服務正在返回瘋狂的響應。 有時它會將響應從一個服務發送到另一個服務,例如,運行get User服務,我希望收到一個User對象,但是收到了其他業務對象,例如Address或任何其他隨機對象,甚至有時我收到了html錯誤消息Tomcat或響應為空。

查看我發現的日志:

SEVERE: Error while closing the output stream in order to commit response.
java.lang.NullPointerException
    at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:215)
    at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:480)
    at org.apache.coyote.http11.InternalOutputBuffer.endRequest(InternalOutputBuffer.java:159)
    at org.apache.coyote.http11.AbstractHttp11Processor.action(AbstractHttp11Processor.java:758)
    at org.apache.coyote.Response.action(Response.java:174)
    at org.apache.coyote.Response.finish(Response.java:291)
    at org.apache.catalina.connector.OutputBuffer.close(OutputBuffer.java:320)
    at org.apache.catalina.connector.CoyoteOutputStream.close(CoyoteOutputStream.java:108)
    at org.glassfish.jersey.message.internal.CommittingOutputStream.close(CommittingOutputStream.java:277)
    at org.glassfish.jersey.message.internal.OutboundMessageContext.close(OutboundMessageContext.java:834)
    at org.glassfish.jersey.server.ContainerResponse.close(ContainerResponse.java:411)
    at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:691)
    at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:377)
    at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:367)
    at org.glassfish.jersey.server.ServerRuntime$AsyncResponder$3.run(ServerRuntime.java:828)
    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:297)
    at org.glassfish.jersey.server.ServerRuntime$AsyncResponder.resume(ServerRuntime.java:858)
    at org.glassfish.jersey.server.ServerRuntime$AsyncResponder.resume(ServerRuntime.java:820)
    at com.compuware.ruxit.synthetic.api.resource.test.TestDispatcherResource.poll(TestDispatcherResource.java:111)
    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:606)
    at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:151)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:171)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$VoidOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:136)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:104)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:387)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.access$100(ResourceMethodInvoker.java:103)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker$2.call(ResourceMethodInvoker.java:320)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker$2.call(ResourceMethodInvoker.java:317)
    at org.glassfish.jersey.server.ServerRuntime$AsyncResponder$2$1.run(ServerRuntime.java:791)
    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:297)
    at org.glassfish.jersey.server.ServerRuntime$AsyncResponder$2.run(ServerRuntime.java:787)Nul
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

最初,我認為這與使Swagger正常工作的新servlet定義有關:

<servlet>
    <servlet-name>SwaggerConfig</servlet-name>
    <servlet-class>com.compuware.ruxit.synthetic.api.configuration.SwaggerJaxrsConfig</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>

我嘗試將<async-supported>true</async-supported>到SwaggerConfig servlet和Jersey servlet定義中(當您使用ManagedAsync批注時這不是必需的,但是我嘗試了一下)。 但這沒有幫助。

發現我正在使用招搖的maven依賴項:

    <dependency>
        <groupId>com.wordnik</groupId>
        <artifactId>swagger-jersey2-jaxrs_2.10</artifactId>
        <version>1.3.5</version>
    </dependency>

對jersey-container-servlet-core有依賴性,但是比我在jersey依賴性中已經擁有的版本要舊,我使用2.10時為2.1。 然后,Maven會使用它並覆蓋我的球衣應用程序所需的那個。

我所做的只是要排除該傳遞依賴項:

    <dependency>
        <groupId>com.wordnik</groupId>
        <artifactId>swagger-jersey2-jaxrs_2.10</artifactId>
        <version>1.3.5</version>
        <exclusions>
            <exclusion>
                <artifactId>jersey-container-servlet-core</artifactId>
                <groupId>org.glassfish.jersey.containers</groupId>
            </exclusion>
        </exclusions>
    </dependency>

在該更新之后,到目前為止還沒有出現異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM