title: Asynchronous Jersey 2 REST in liferay vaadin portlet
body: <p>Currently I have a standalone Jersey 2.x web app in my liferay tomcat container, set to run asynchronously. I also have my main portlet in Liferay built with Vaadin.</p>
  
  <p>I want to move my REST service to my vaadin project, so that I can leverage hibernate and caching from my main app.</p>
  
  <p>However, when I move all the code over, and the servlet entry in the web.xml file, it throws the exception below when I make a GET call to the service.</p>
  
  <p>Has anybody accomplished this? I am thinking it has something to with the asynchronous functionality, or maybe spring? I am running Liferay 6.1.1 GA2.</p>
  
  <pre><code>`SEVERE: Servlet.service() for servlet [TEKControl RESTFul API] in context with path [/tekwave-portlet] threw exception [javax.ws.rs.ProcessingExceptio`
  
  `n: Attempt to suspend a connection of an asynchronous request failed in the underlying container.] with root cause`
  
  `javax.ws.rs.ProcessingException: Attempt to suspend a connection of an asynchronous request failed in the underlying container.`
  
  
  at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:331)
  at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:106)
  at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:259)
  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:318)
  at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:236)
  at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1010)
  at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:373)
  at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:382)
  at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:345)
  at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:220)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
  at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:72)
  at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
  at sun.reflect.GeneratedMethodAccessor386.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:601)
  at com.liferay.portal.kernel.bean.ClassLoaderBeanHandler.invoke(ClassLoaderBeanHandler.java:67)
  at $Proxy526.doFilter(Unknown Source)
  at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:72)
  at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDirectCallFilter(InvokerFilterChain.java:167)
  at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:95)
  at com.liferay.portal.kernel.servlet.PortalClassLoaderFilter.doFilter(PortalClassLoaderFilter.java:70)
  at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:206)
  at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:108)
  at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilter.doFilter(InvokerFilter.java:73)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
  at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
  at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
  at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
  at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
  at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1813)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
  at java.lang.Thread.run(Thread.java:722) 
  </code></pre>
  
  <p><strong>UPDATE</strong></p>
  
  <p>When I debug this, it reaches the class I'm calling with a GET request, but it throws the error after declaring some things and before going into the GET method.  Below is my GET method declaration:</p>
  
  <pre><code>@GET
  @Produces("application/xml")
  public void AnswerPhoneCall(@Suspended final AsyncResponse asyncResponse, @Context UriInfo ui) {
      final MultivaluedMap&lt;String, String&gt; queryParams = ui.getQueryParameters();
  
      new Thread(new Runnable() {
          @Override
          public void run() {
              String ret = "Testing";
              asyncResponse.resume(ret);
          }
      }).start();
  }
  </code></pre>
  
  <p><strong>----WORKING SOLUTION---</strong></p>
  
  <p>Since the liferay invoker filter was causing the issue, and I also don't think Liferay fully supports Servlet 3.0 yet, below is what we came up with to solve this problem.</p>
  
  <p>Add a class that implements "org.glassfish.jersey.servlet.ServletContainer"</p>
  
  <pre><code>import org.apache.catalina.Globals;
  import javax.servlet.ServletException;
  import javax.servlet.ServletRequest;
  import javax.servlet.ServletResponse;
  import java.io.IOException;
  
  public class ServletContainer extends org.glassfish.jersey.servlet.ServletContainer {
  
      @Override
      public void service(ServletRequest request, ServletResponse response)
              throws ServletException, IOException {
          request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, true);
          super.service(request, response);
      }
  }
  </code></pre>
  
  <p>Change your servlet entry in the portlet web.xml to the above class:</p>
  
  <pre><code>&lt;servlet&gt;
      &lt;servlet-name&gt;RESTFul API&lt;/servlet-name&gt;
      &lt;servlet-class&gt;com.myportlet.api.jersey.ServletContainer&lt;/servlet-class&gt;
      &lt;init-param&gt;
          &lt;param-name&gt;jersey.config.server.provider.packages&lt;/param-name&gt;
          &lt;param-value&gt;com.myportlet.api&lt;/param-value&gt;
      &lt;/init-param&gt;
      &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
      &lt;async-supported&gt;true&lt;/async-supported&gt;
  &lt;/servlet&gt;
  &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;RESTFul API&lt;/servlet-name&gt;
      &lt;url-pattern&gt;/api/*&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
  </code></pre>
  
  <p>Add the following dependency in maven, if that is what you use</p>
  
  <pre><code>&lt;dependency&gt;
      &lt;groupId&gt;org.apache.geronimo.ext.tomcat&lt;/groupId&gt;
      &lt;artifactId&gt;catalina&lt;/artifactId&gt;
      &lt;version&gt;7.0.39.1&lt;/version&gt;
      &lt;scope&gt;provided&lt;/scope&gt;
  &lt;/dependency&gt;
  </code></pre>