4 Replies Latest reply on Apr 2, 2012 4:34 PM by lightguard

    Seam-Security Preventing Resteasy Async Calls

    mister_s

      Hi everyone,

       

      I'm building a REST web-application using JBoss 7.1, Resteasy and Seam-Security. While regular REST calls work splendid, when adding seam-security to the application, asynchronous calls throw an exception.

       

      Here's my example application:

       

      {code}

      package com.example.test.polling;

       

      import javax.ws.rs.ApplicationPath;

      import javax.ws.rs.core.Application;

       

      @ApplicationPath("/")

      public class JaxRsConfig extends Application {

      }

      {code}

       

      and the REST endpoint:

       

      {code}

      package com.example.test.polling;

       

      import javax.ws.rs.GET;

      import javax.ws.rs.Path;

      import javax.ws.rs.Produces;

      import javax.ws.rs.core.MediaType;

      import javax.ws.rs.core.Response;

      import javax.ws.rs.core.Response.ResponseBuilder;

       

      import org.jboss.resteasy.annotations.Suspend;

      import org.jboss.resteasy.spi.AsynchronousResponse;

       

      @Path("/poll")

      public class PollingRestService {

       

          @GET

          @Path("/get")

          @Produces(MediaType.TEXT_PLAIN)

          public String syncGet() {

              System.out.println("syncGet() was called");

              return "all ok";

          }

       

          @GET

          @Path("/async")

          @Produces(MediaType.TEXT_PLAIN)

          public void getAsync(@Suspend(1000) final AsynchronousResponse response) {

              Thread t = new Thread() {

                  @Override

                  public void run() {

                      try {

                          System.out.println("getAsync(): running thread");

                          sleep(10 * 1000); // 10s

       

                          ResponseBuilder ok = Response.ok("all ok on this side", MediaType.TEXT_PLAIN);

                          Response jaxrs = ok.build();

                          response.setResponse(jaxrs);

       

                          System.out.println("getAsync(): response sent");

                      } catch (Exception e) {

                          e.printStackTrace();

                      }

                  }

              };

              t.start();

          }

      }

      {code}

       

       

      This very code works beautifully as long as seam-security is not present. When adding seam-security to my pom file's dependencies (I don't even have to use it in some class!), calling the async method (using "/poll/async" in my browser) produces the following exception:

       

      {code}

      19:22:21,773 SEVERE [org.jboss.resteasy.core.SynchronousDispatcher] (http--127.0.0.1-8080-2) Failed executing GET poll/async: org.jboss.resteasy.spi.BadRequestException: Failed processing arguments of public void com.example.test.polling.PollingRestService.getAsync(org.jboss.resteasy.spi.AsynchronousResponse)

              at org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:139) [resteasy-jaxrs-2.3.1.GA.jar:]

              at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:147) [resteasy-jaxrs-2.3.1.GA.jar:]

              at org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:257) [resteasy-jaxrs-2.3.1.GA.jar:]

              at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:222) [resteasy-jaxrs-2.3.1.GA.jar:]

              at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:211) [resteasy-jaxrs-2.3.1.GA.jar:]

              at org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:525) [resteasy-jaxrs-2.3.1.GA.jar:]

              at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:502) [resteasy-jaxrs-2.3.1.GA.jar:]

              at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:119) [resteasy-jaxrs-2.3.1.GA.jar:]

              at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:208) [resteasy-jaxrs-2.3.1.GA.jar:]

              at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55) [resteasy-jaxrs-2.3.1.GA.jar:]

              at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:50) [resteasy-jaxrs-2.3.1.GA.jar:]

              at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]

              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.10.Final.jar:]

              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:]

              at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]

              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.10.Final.jar:]

              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:]

              at org.jboss.solder.servlet.exception.CatchExceptionFilter.doFilter(CatchExceptionFilter.java:65) [solder-impl-3.1.0.Final.jar:3.1.0.Final]

              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.10.Final.jar:]

              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:]

              at org.jboss.solder.servlet.event.ServletEventBridgeFilter.doFilter(ServletEventBridgeFilter.java:74) [solder-impl-3.1.0.Final.jar:3.1.0.Final]

              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.10.Final.jar:]

              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:]

              at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.10.Final.jar:]

              at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.10.Final.jar:]

              at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:154) [jboss-as-web-7.1.0.Final.jar:7.1.0.Final]

              at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.10.Final.jar:]

              at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.10.Final.jar:]

              at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.10.Final.jar:]

              at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.10.Final.jar:]

              at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.10.Final.jar:]

              at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.10.Final.jar:]

              at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.10.Final.jar:]

              at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_26]

      Caused by: java.lang.IllegalStateException: The servlet or filters that are being used by this request do not support async operation

              at org.apache.catalina.connector.Request.startAsync(Request.java:3203) [jbossweb-7.0.10.Final.jar:]

              at org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:1001) [jbossweb-7.0.10.Final.jar:]

              at org.jboss.resteasy.plugins.server.servlet.Servlet3AsyncHttpRequest.createAsynchronousResponse(Servlet3AsyncHttpRequest.java:39) [async-http-servlet-3.0-2.3.1.GA.jar:]

              at org.jboss.resteasy.core.SuspendInjector.inject(SuspendInjector.java:30) [resteasy-jaxrs-2.3.1.GA.jar:]

              at org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:124) [resteasy-jaxrs-2.3.1.GA.jar:]

              ... 33 more

      {code}

       

      It looks to me that the call somehow gets routed to SynchronousDispatcher, and then fails.

       

      Has anyone an idea why this happens, and how I can prevent it (and thus resolve the exception)? Why has adding seam an effect on how the call is dispatched? Is it a bug in seam (should I file an issue)?

       

      I'm using the latest versions of everything:

      • JBoss AS 7.1.0.Final
      • seam-security 3.1.0.Final
      • resteasy 2.3.1.GA

       

      Here's the dependency section of my pom file (full pom.xml and other code attached):

      {code:xml}

      <dependencies>

          <!-- The complete J6EE stack in one BOM -->

          <dependency>

              <groupId>org.jboss.spec</groupId>

              <artifactId>jboss-javaee-web-6.0</artifactId>

              <version>2.0.0.Final</version>

              <type>pom</type>

              <scope>provided</scope>

          </dependency>

          <dependency>

              <groupId>commons-lang</groupId>

              <artifactId>commons-lang</artifactId>

              <version>2.6</version>

          </dependency>

       

       

          <!-- Adding Seam crashes async calls! -->

          <dependency>

              <groupId>org.jboss.seam.security</groupId>

              <artifactId>seam-security</artifactId>

              <version>3.1.0.Final</version>

          </dependency>

       

       

          <!-- Implicity dependency by seam... -->

          <dependency>

              <groupId>joda-time</groupId>

              <artifactId>joda-time</artifactId>

              <version>2.0</version>

              <scope>runtime</scope>

          </dependency>

       

       

          <dependency>

              <groupId>org.hibernate</groupId>

              <artifactId>hibernate-core</artifactId>

              <version>4.1.1.Final</version>

          </dependency>

       

       

          <dependency>

              <groupId>org.slf4j</groupId>

              <artifactId>slf4j-api</artifactId>

              <version>1.6.1</version>

              <scope>provided</scope>

          </dependency>

          <!-- drools is marked as optional by seam-security, but we need it -->

          <dependency>

              <groupId>org.drools</groupId>

              <artifactId>drools-core</artifactId>

              <version>5.3.1.Final</version>

          </dependency>

          <dependency>

              <groupId>org.drools</groupId>

              <artifactId>drools-compiler</artifactId>

              <version>5.3.1.Final</version>

              <!-- There seems to be some antlr version mismatch, so we have to exclude drools-compiler's dependencies on it -->

              <exclusions>

                  <exclusion>

                  <groupId>org.antlr</groupId>

                  <artifactId>antlr-runtime</artifactId>

                  </exclusion>

                  <exclusion>

                  <groupId>org.antlr</groupId>

                  <artifactId>antlr</artifactId>

                  </exclusion>

                  <exclusion>

                  <groupId>org.antlr</groupId>

                  <artifactId>stringtemplate</artifactId>

                  </exclusion>

                  <exclusion>

                  <groupId>org.antlr</groupId>

                  <artifactId>gunit</artifactId>

                  </exclusion>

                  <exclusion>

                  <groupId>antlr</groupId>

                  <artifactId>antlr</artifactId>

                  </exclusion>

              </exclusions>

          </dependency>

       

       

          <dependency>

              <groupId>org.jboss.spec.javax.servlet</groupId>

              <artifactId>jboss-servlet-api_3.0_spec</artifactId>

              <scope>compile</scope>

              <version>1.0.0.Final</version>

          </dependency>

       

       

          <!-- ASYNC support -->

          <dependency>

              <groupId>org.jboss.resteasy</groupId>

              <artifactId>resteasy-jaxrs</artifactId>

              <version>2.3.1.GA</version>

              <scope>provided</scope>

          </dependency>

          <dependency>

              <groupId>org.jboss.resteasy</groupId>

              <artifactId>async-http-servlet-3.0</artifactId>

              <version>2.3.1.GA</version>

              <scope>provided</scope>

          </dependency>

      </dependencies>

       

      {code}