users@jersey.java.net

Re: [Jersey] Critical FormParam degradation

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Wed, 05 May 2010 16:14:53 +0200

Hi Santi,

Very hard to know what is going on here. Cross posting to the
atmosphere list as well.

Some questions:

1) Do you have a reproducible test case, preferably a maven project?

2) Anything in the logs?

3) How are you deploying? using Grizzly directly or a Web server like
Jetty or Tomcat?

For servlet-based apps Jersey processes requests using
HttpServletRequest and does not do anything special with it. Thus i
suspect this is an issue at a lower level, perhaps Grizzly or the
Atmosphere CPR.

The log output "A servlet POST request..." indicates that request
entity is empty, so Jersey attempts to re-create the form information
from HttpServletRequest.getParameterMap. It would make sense that you
only get that message logged just before a failure when the request
entity is empty.

Paul.

On May 5, 2010, at 3:36 PM, Santi Manninen wrote:

> Hi,
>
> I've been having a really strange problem with gradually losing
> @FormParam contents.
> It's a linear degradation, first all requests work for a while,
> after about an hour it's occasional (retry sometimes works), then
> after a few hours it's constant. I'm using Jersey in Akka, and it
> happens at least in Akka 0.7.1 with Scala 2.7.7 and in 0.8.1 and
> 2.8.0.Beta1, both of which use Jersey 1.1.5. I have also mailed the
> Akka list about this but I suspect it's a Jersey / Atmosphere /
> Grizzly issue...
>
> Originally I was passing JSON in the body and reading it with an
> InputStream and sometimes the InputStream would have length 0. I
> tried to work around it by using @FormParam instead and passing the
> json in an application/x-www-form-urlencoded body. Didn't solve the
> problem, and now after a while the FormParam, just like the
> InputStream before it, is empty.
>
> I'm just running the Akka kernel from eg.
> akka_2.8.0.Beta1-0.8.1.jar. Letting this code run for a while with a
> few occasional requests causes it:
>
> @Path("/test")
> class FakeService extends Actor {
> @POST
> def testIt(@FormParam("json") json: String): String = {
> log.info("received json:"+json)
> json
> }
> def receive = {
> case _ =>
> }
> }
>
> After a while, json is null.
>
> WAR [20100505-15:05:47.108] servlet: A servlet POST request, to the
> URI http://localhost:9998/test, contains form parameters in the
> request body but the request body has been consumed by the servlet
> or a servlet filter accessing the request parameters. Only resource
> methods using @FormParam will work as expected. Resource methods
> consuming the request body by other means will not work as expected.
> INF [20100505-15:05:47.108] fake: received json:null
>
> Here's a stack trace from trying to use the json.
>
> java.lang.NullPointerException
> at my.FakeService.testIt(FakeService.scala:16)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun
> .reflect
> .NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at
> sun
> .reflect
> .DelegatingMethodAccessorImpl
> .invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at
> com
> .sun
> .jersey
> .server
> .impl.model.method.dispatch.AbstractResourceMethodDispatchProvider
> $
> TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:
> 149)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .model
> .method
> .dispatch
> .ResourceJavaMethodDispatcher
> .dispatch(ResourceJavaMethodDispatcher.java:67)
> at
> com
> .sun
> .jersey
> .server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:259)
> at
> com
> .sun
> .jersey
> .server
> .impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:83)
> at
> com
> .sun
> .jersey
> .server
> .impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:133)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .uri
> .rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:71)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl._handleRequest(WebApplicationImpl.java:990)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:941)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:932)
> at
> com
> .sun
> .jersey.spi.container.servlet.WebComponent.service(WebComponent.java:
> 384)
> at
> com
> .sun
> .jersey
> .spi
> .container.servlet.ServletContainer.service(ServletContainer.java:451)
> at
> com
> .sun
> .jersey
> .spi
> .container.servlet.ServletContainer.service(ServletContainer.java:632)
> at se.scalablesolutions.akka.comet.AkkaServlet$$anon$1$$anon
> $2.onRequest(AkkaServlet.scala:33)
> at se.scalablesolutions.akka.comet.AkkaServlet$$anon
> $1.onRequest(AkkaServlet.scala:43)
> at
> org
> .atmosphere
> .cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:145)
> at
> org
> .atmosphere
> .cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:119)
> at
> org
> .atmosphere
> .container.GrizzlyCometSupport.service(GrizzlyCometSupport.java:99)
> at
> org
> .atmosphere
> .cpr.AtmosphereServlet.doCometSupport(AtmosphereServlet.java:803)
> at
> org.atmosphere.cpr.AtmosphereServlet.doPost(AtmosphereServlet.java:
> 786)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:
> 727)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:
> 820)
> at
> com
> .sun
> .grizzly.http.servlet.FilterChainImpl.doFilter(FilterChainImpl.java:
> 195)
> at
> com
> .sun
> .grizzly
> .http.servlet.FilterChainImpl.invokeFilterChain(FilterChainImpl.java:
> 139)
> at
> com
> .sun
> .grizzly.http.servlet.ServletAdapter.doService(ServletAdapter.java:
> 376)
> at
> com
> .sun.grizzly.http.servlet.ServletAdapter.service(ServletAdapter.java:
> 324)
> at
> com
> .sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:
> 166)
> at
> com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:
> 791)
> at
> com.sun.grizzly.comet.CometEngine.executeServlet(CometEngine.java:473)
> at com.sun.grizzly.comet.CometEngine.handle(CometEngine.java:
> 341)
> at
> com
> .sun.grizzly.comet.CometAsyncFilter.doFilter(CometAsyncFilter.java:84)
> at
> com
> .sun
> .grizzly
> .arp.DefaultAsyncExecutor.invokeFilters(DefaultAsyncExecutor.java:161)
> at
> com
> .sun
> .grizzly
> .arp.DefaultAsyncExecutor.interrupt(DefaultAsyncExecutor.java:137)
> at
> com
> .sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:88)
> at com.sun.grizzly.http.TaskBase.run(TaskBase.java:189)
> at com.sun.grizzly.util.AbstractThreadPool
> $Worker.doWork(AbstractThreadPool.java:330)
> at com.sun.grizzly.util.AbstractThreadPool
> $Worker.run(AbstractThreadPool.java:309)
> at java.lang.Thread.run(Thread.java:619)
>
> It's a very hard to find bug and I would greatly appreciate any help!
>
> Thanks.
>
> Best regards,
>
> Santi