Wessel Oosthuizen
Wessel Oosthuizen

Reputation: 73

Asynchronous Jersey 2 REST in liferay vaadin portlet

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.

I want to move my REST service to my vaadin project, so that I can leverage hibernate and caching from my main app.

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.

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.

`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) 

UPDATE

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:

@GET
@Produces("application/xml")
public void AnswerPhoneCall(@Suspended final AsyncResponse asyncResponse, @Context UriInfo ui) {
    final MultivaluedMap<String, String> queryParams = ui.getQueryParameters();

    new Thread(new Runnable() {
        @Override
        public void run() {
            String ret = "Testing";
            asyncResponse.resume(ret);
        }
    }).start();
}

----WORKING SOLUTION---

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.

Add a class that implements "org.glassfish.jersey.servlet.ServletContainer"

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);
    }
}

Change your servlet entry in the portlet web.xml to the above class:

<servlet>
    <servlet-name>RESTFul API</servlet-name>
    <servlet-class>com.myportlet.api.jersey.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>com.myportlet.api</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <async-supported>true</async-supported>
</servlet>
<servlet-mapping>
    <servlet-name>RESTFul API</servlet-name>
    <url-pattern>/api/*</url-pattern>
</servlet-mapping>

Add the following dependency in maven, if that is what you use

<dependency>
    <groupId>org.apache.geronimo.ext.tomcat</groupId>
    <artifactId>catalina</artifactId>
    <version>7.0.39.1</version>
    <scope>provided</scope>
</dependency>

Upvotes: 0

Views: 1134

Answers (2)

Rushikesh Thakkar
Rushikesh Thakkar

Reputation: 723

AFAIU, it has Nothing to do with connector property. Basically what is happening is Liferay's filter is trying to intercept the request to the Jersey REST Webservice servlets. You may need to change Filter mappings of Liferay's filters in web.xml to exclude Jersey's servlets.

Another, possibly cleaner approach is that you may want to develop a "Web" plugin to host your REST services project. I haven't tried this, but you may want to explore possibilities in this direction.

Upvotes: 0

Gautam
Gautam

Reputation: 3386

can you please check connector property in server.xml

<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
               connectionTimeout="20000"
               redirectPort="8443" />

Upvotes: 0

Related Questions