2016-10-31 16 views
0

私は現在、Resteasyで作成したRESTful APIテストを手助けするためにTJWSEmbeddedJaxrsServerを使用しています。 しかし、呼び出されたメソッドのいずれかがExceptionをスローすると、問題が発生します.Reastasy Clientは "失われ"、接続を保持し、他のテストメソッドがRESTfulサービスを呼び出すことはできません。これは、例外をアンラップして組み込みサーバーで使用できるプロバイダをインスタンス化しても発生します。Resteasyメソッドが例外をスローした後にクライアントが接続を保持する

誰でも助けてくれますか?

問題をシミュレートするために、それは簡単で、実際です:

パブリッククラスInMemoryRestTest {:

  1. はこのようになりhttps://github.com/mp911de/rest-api-test
  2. 変更テストクラスにマークPaluchが提供するサンプルをダウンロード

    @Path("/myresource") 
    public static class MyResource { 
    
        @POST 
        @Consumes(MediaType.TEXT_PLAIN) 
        @Produces(MediaType.APPLICATION_XML) 
        public MyModel createMyModel(int number) throws Exception { 
         // supose this is a Business exception 
         throw new Exception("Test"); 
        } 
    
    } 
    
    public static MyResource sut = new MyResource(); 
    public static InMemoryRestServer server; 
    
    @BeforeClass 
    public static void beforeClass() throws Exception { 
        server = InMemoryRestServer.create(sut); 
    } 
    
    @AfterClass 
    public static void afterClass() throws Exception { 
        server.close(); 
    } 
    
    @Test 
    public void postSimpleBody() throws Exception { 
        // This one throws the "Exception" exception and passes  
        Response response = server.newRequest("/myresource").request().buildPost(Entity.text("42")).invoke(); 
        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus()); 
    } 
    
    @Test 
    public void postAnother() throws Exception { 
        // This one fails with "Invalid use of BasicClientConnManager: connection still allocated." 
        Response response = server.newRequest("/myresource").request().buildPost(Entity.text("20")).invoke(); 
        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus()); 
    } 
    

    }

    そしてボイル! 「postAnother()」の実行のためのテストは、次のエラーが発生しますとき:

    javax.ws.rs.ProcessingException: Unable to invoke request 
        at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:287) 
        at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:407) 
        at biz.paluch.rest.test.InMemoryRestTest.postSimpleBody(InMemoryRestTest.java:51) 
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
        at java.lang.reflect.Method.invoke(Method.java:498) 
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) 
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) 
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 
    Caused by: java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated. 
    Make sure to release the connection before allocating another one. 
        at org.apache.http.impl.conn.BasicClientConnectionManager.getConnection(BasicClientConnectionManager.java:162) 
        at org.apache.http.impl.conn.BasicClientConnectionManager$1.getConnection(BasicClientConnectionManager.java:139) 
        at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:456) 
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906) 
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805) 
        at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:283) 
        ... 27 more 
    

答えて

1

(両方けれどもてAssertionErrorをスローするように見える)、次のよう

//this.resteasyClient = new ResteasyrestEasyClientBuilder().build(); 
ResteasyrestEasyClientBuilder restEasyClientBuilder = new ResteasyrestEasyClientBuilder(); 
restEasyClientBuilder = restEasyClientBuilder.connectionPoolSize(20); 
this.resteasyClient = restEasyClientBuilder.build(); 

あなたのテストケースの両方が例外なく実行する必要があります。この道をInMemoryRestServerクラスのwithDefaults()メソッドを変更します。プールは、一度に1つの並列接続だけを持つことができます。 したがって、接続のみを解放するためには、応答(つまりresponse.close())を閉じる必要があります。 https://github.com/resteasy/Resteasy/blob/master/resteasy-client/src/main/java/org/jboss/resteasy/client/jaxrs/internal/ClientResponse.java

public void close() 
    { 
     if (isClosed()) return; 
     try { 
     isClosed = true; 
     releaseConnection(); // <= HERE! 
     } 
     catch (Exception e) { 
     throw new ProcessingException(e); 
     } 
    } 

だからあなたの問題修正する必要があり、以下:

は、ここではレスポンスの実装を参照してください

@Test 
public void postBody() throws Exception {   
    Response response = null; 
    try { 
     response = server.newRequest("...").request().buildPost(Entity.text("...")).invoke();   
    } finally { 
     response.close(); 
    } 
} 

よろしく、

バーナードを。

+0

はい、これが問題を解決しました。レスポンスを閉じると、 "response.readEntity()" throwsとExceptionを呼び出すため、コードを少し変更しなければなりませんでしたが、レスポンスを閉じる前にエンティティをキャプチャすることができました。ありがとう! –

1

をあなたは、接続プールを使用するようにResteasyClientBuilderを設定する必要があります。デフォルトResteasyClientBuilderが接続を使用していない

+1

OK、これは時間的に解決します。これにより、組み込みサーバーが応答を停止する前に20個の例外が発生することができます。しかし、私が本当に必要とするのは、例外が発生した後に接続を解放する方法です。私はそれをどのように達成することができるか知っていますか?ありがとう! –

関連する問題