ChunkedOutput not producing Chunked output on browser

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

ChunkedOutput not producing Chunked output on browser

gschandok
Hi,

I am using org.glassfish.jersey.server.ChunkedOutput to get the chunked response to my request. When I hit the URL through browser, instead of getting output as separate chunks, I am getting all the chunks at once.
But when I use a Test Client to hit the resource, I get the output as separate chunks.

Server Used: Glassfish 4.0
Jersey version 2.13

Resource method is as follows:

@GET
@Path("chunk")
public ChunkedOutput<String> getChunkedResponse(@Context HttpServletRequest request) {

    final ChunkedOutput<String> output = new ChunkedOutput<String>(
            String.class);

    new Thread() {
        public void run() {
            try {
                Thread.sleep(2000);
                String chunk;
                String arr[] = { "America\r\n", "London\r\n", "Delhi\r\n", "null" };
                int i = 0;
                while (!(chunk = arr[i]).equals("null")) {
                    output.write(chunk);
                    i++;
                    Thread.sleep(2000);
                }
            } catch (IOException e) {
                logger.error("IOException : ", e);
            } catch (InterruptedException e) {
                logger.error("InterruptedException : ", e);
                e.printStackTrace();
            } finally {
                try {
                    output.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    logger.error("IOException IN finally : ", e);
                }
            }
        }
    }.start();

    // the output will be probably returned even before
    // a first chunk is written by the new thread
    return output;
}

Test Client method is as follows:

  private static void testChunkedResponse(WebTarget target){
      final Response response = target.path("restRes").path("chunk")
                .request().get();
        final ChunkedInput<String> chunkedInput =
                response.readEntity(new GenericType<ChunkedInput<String>>() {});
        String chunk;
        while ((chunk = chunkedInput.read()) != null) {
            logger.info("Next chunk received: " + chunk);
        }
  }

Can someone please help me understand why response is not getting chunked on browser and what can be done about it?
Reply | Threaded
Open this post in threaded view
|

Re: ChunkedOutput not producing Chunked output on browser

gschandok
Also, if I try to instantiate the ChunkedOutput using statement --
final ChunkedOutput<String> output = new ChunkedOutput<String>(String.class, "");

I get the following exception

2014-12-03T09:11:46.242-0800|WARNING: StandardWrapperValve[Jersey REST Service]: Servlet.service() for servlet Jersey REST Service threw exception
java.lang.NoSuchMethodError: org.glassfish.jersey.server.ChunkedOutput.<init>(Ljava/lang/reflect/Type;Ljava/lang/String;)V
        at res.RestResource.getChunkedResponse(RestResource.java:52)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:125)
        at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:195)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:91)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:346)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:341)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:101)
        at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:224)
        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:317)
        at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:198)
        at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:946)
        at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:323)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
        at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
        at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
        at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
        at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
        at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
        at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
        at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
        at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
        at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
        at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
        at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
        at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
        at java.lang.Thread.run(Thread.java:745)

But on the other hand, if I use the statement,
    final ChunkedOutput<String> output = new ChunkedOutput<String>(String.class);
it does not throw any exception.
Can someone please explain me why it is not allowing me to use this overloaded version of ChunkedOutput constructor?
Reply | Threaded
Open this post in threaded view
|

Re: ChunkedOutput not producing Chunked output on browser

Santiago Pericas-Geertsen-2
In reply to this post by gschandok

 Is there JS code that reads this or just the browser? If the latter, I don't understand how you intend to you use these chunks. Have you checked the browser's cache?

-- Santiago

On Dec 3, 2014, at 10:28 PM, gschandok <[hidden email]> wrote:

> Hi,
>
> I am using org.glassfish.jersey.server.ChunkedOutput to get the chunked
> response to my request. When I hit the URL through browser, instead of
> getting output as separate chunks, I am getting all the chunks at once.
> But when I use a Test Client to hit the resource, I get the output as
> separate chunks.
>
> Server Used: Glassfish 4.0
> Jersey version 2.13
>
> Resource method is as follows:
>
> @GET
> @Path("chunk")
> public ChunkedOutput<String> getChunkedResponse(@Context HttpServletRequest
> request) {
>
>    final ChunkedOutput<String> output = new ChunkedOutput<String>(
>            String.class);
>
>    new Thread() {
>        public void run() {
>            try {
>                Thread.sleep(2000);
>                String chunk;
>                String arr[] = { "America\r\n", "London\r\n", "Delhi\r\n",
> "null" };
>                int i = 0;
>                while (!(chunk = arr[i]).equals("null")) {
>                    output.write(chunk);
>                    i++;
>                    Thread.sleep(2000);
>                }
>            } catch (IOException e) {
>                logger.error("IOException : ", e);
>            } catch (InterruptedException e) {
>                logger.error("InterruptedException : ", e);
>                e.printStackTrace();
>            } finally {
>                try {
>                    output.close();
>                } catch (IOException e) {
>                    // TODO Auto-generated catch block
>                    logger.error("IOException IN finally : ", e);
>                }
>            }
>        }
>    }.start();
>
>    // the output will be probably returned even before
>    // a first chunk is written by the new thread
>    return output;
> }
>
> Test Client method is as follows:
>
>  private static void testChunkedResponse(WebTarget target){
>      final Response response = target.path("restRes").path("chunk")
>                .request().get();
>        final ChunkedInput<String> chunkedInput =
>                response.readEntity(new
> GenericType<ChunkedInput&lt;String>>() {});
>        String chunk;
>        while ((chunk = chunkedInput.read()) != null) {
>            logger.info("Next chunk received: " + chunk);
>        }
>  }
>
> Can someone please help me understand why response is not getting chunked on
> browser and what can be done about it?
>
>
>
>
> --
> View this message in context: http://jersey.576304.n2.nabble.com/ChunkedOutput-not-producing-Chunked-output-on-browser-tp7582908.html
> Sent from the Jersey mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

Re: ChunkedOutput not producing Chunked output on browser

Marek Potociar
In reply to this post by gschandok
Chances are you are running a server with Jersey version lower than 2.4.1 - that constructor has been added in Jersey 2.4.1 - see the constructor javadoc.

Cheers,
Marek

On 04 Dec 2014, at 04:36, gschandok <[hidden email]> wrote:

Also, if I try to instantiate the ChunkedOutput using statement --
final ChunkedOutput<String> output = new ChunkedOutput<String>(String.class,
"");

I get the following exception

2014-12-03T09:11:46.242-0800|WARNING: StandardWrapperValve[Jersey REST
Service]: Servlet.service() for servlet Jersey REST Service threw exception
java.lang.NoSuchMethodError:
org.glassfish.jersey.server.ChunkedOutput.<init>(Ljava/lang/reflect/Type;Ljava/lang/String;)V
at res.RestResource.getChunkedResponse(RestResource.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at
org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
at
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:125)
at
org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:195)
at
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:91)
at
org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:346)
at
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:341)
at
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:101)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:224)
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:317)
at
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:198)
at
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:946)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:323)
at
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
at
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
at
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
at
org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at
org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at
org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
at
com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
at
org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
at
org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
at
org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
at
org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at
org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
at
org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
at
org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
at
org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
at
org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at
org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
at
org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
at
org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
at
org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
at
org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
at
org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
at
org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
at java.lang.Thread.run(Thread.java:745)

But on the other hand, if I use the statement,
   final ChunkedOutput<String> output = new
ChunkedOutput<String>(String.class);
it does not throw any exception.
Can someone please explain me why it is not allowing me to use this
overloaded version of ChunkedOutput constructor?



--
View this message in context: http://jersey.576304.n2.nabble.com/ChunkedOutput-not-producing-Chunked-output-on-browser-tp7582908p7582909.html
Sent from the Jersey mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

Re: ChunkedOutput not producing Chunked output on browser

Marek Potociar
In reply to this post by gschandok
The most likely reason is that the browser is caching the response data and only displays the result once all the response data are received.

Marek

> On 04 Dec 2014, at 04:28, gschandok <[hidden email]> wrote:
>
> Hi,
>
> I am using org.glassfish.jersey.server.ChunkedOutput to get the chunked
> response to my request. When I hit the URL through browser, instead of
> getting output as separate chunks, I am getting all the chunks at once.
> But when I use a Test Client to hit the resource, I get the output as
> separate chunks.
>
> Server Used: Glassfish 4.0
> Jersey version 2.13
>
> Resource method is as follows:
>
> @GET
> @Path("chunk")
> public ChunkedOutput<String> getChunkedResponse(@Context HttpServletRequest
> request) {
>
>    final ChunkedOutput<String> output = new ChunkedOutput<String>(
>            String.class);
>
>    new Thread() {
>        public void run() {
>            try {
>                Thread.sleep(2000);
>                String chunk;
>                String arr[] = { "America\r\n", "London\r\n", "Delhi\r\n",
> "null" };
>                int i = 0;
>                while (!(chunk = arr[i]).equals("null")) {
>                    output.write(chunk);
>                    i++;
>                    Thread.sleep(2000);
>                }
>            } catch (IOException e) {
>                logger.error("IOException : ", e);
>            } catch (InterruptedException e) {
>                logger.error("InterruptedException : ", e);
>                e.printStackTrace();
>            } finally {
>                try {
>                    output.close();
>                } catch (IOException e) {
>                    // TODO Auto-generated catch block
>                    logger.error("IOException IN finally : ", e);
>                }
>            }
>        }
>    }.start();
>
>    // the output will be probably returned even before
>    // a first chunk is written by the new thread
>    return output;
> }
>
> Test Client method is as follows:
>
>  private static void testChunkedResponse(WebTarget target){
>      final Response response = target.path("restRes").path("chunk")
>                .request().get();
>        final ChunkedInput<String> chunkedInput =
>                response.readEntity(new
> GenericType<ChunkedInput&lt;String>>() {});
>        String chunk;
>        while ((chunk = chunkedInput.read()) != null) {
>            logger.info("Next chunk received: " + chunk);
>        }
>  }
>
> Can someone please help me understand why response is not getting chunked on
> browser and what can be done about it?
>
>
>
>
> --
> View this message in context: http://jersey.576304.n2.nabble.com/ChunkedOutput-not-producing-Chunked-output-on-browser-tp7582908.html
> Sent from the Jersey mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

Re: ChunkedOutput not producing Chunked output on browser

gschandok
In reply to this post by Santiago Pericas-Geertsen-2
No, there is no JS code that reads it, it's the browser directly.

I simply expect the response to display as separate chunks on the browser, right at the same moment when I write it into the ChunkedOutput using write(chunk) method.
Reply | Threaded
Open this post in threaded view
|

Re: ChunkedOutput not producing Chunked output on browser

gschandok
In reply to this post by Marek Potociar
If Browser is caching the data then how can I achieve chunking in this case.
I have tried after clearing the browsing history but result was the same.

Reply | Threaded
Open this post in threaded view
|

Re: ChunkedOutput not producing Chunked output on browser

gschandok
In reply to this post by Marek Potociar
Yes, you are right about the version of the Jersey.
I have now installed Glassfish 4.1.0 which has Jersey 2.10.4.

So, now it does not fail with that exception.

But the ultimate objective is still not met. I am still not getting the chunked output.

It seems that only when we close the response, the data gets flushed and not before.
Reply | Threaded
Open this post in threaded view
|

Re: ChunkedOutput not producing Chunked output on browser

Noah
I think its on by default, but you should double check that your Glassfish HTTP listener has chunked encoding enabled.


On Fri, Dec 5, 2014 at 12:22 AM, gschandok <[hidden email]> wrote:
Yes, you are right about the version of the Jersey.
I have now installed Glassfish 4.1.0 which has Jersey 2.10.4.

So, now it does not fail with that exception.

But the ultimate objective is still not met. I am still not getting the
chunked output.

It seems that only when we close the response, the data gets flushed and not
before.




--
View this message in context: http://jersey.576304.n2.nabble.com/ChunkedOutput-not-producing-Chunked-output-on-browser-tp7582908p7582923.html
Sent from the Jersey mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

Re: ChunkedOutput not producing Chunked output on browser

gschandok
Thank you so much for replying!!

Could you please tell me how can I enable this Chunked Encoding on Glassfish HTTP Listener.
Reply | Threaded
Open this post in threaded view
|

Re: ChunkedOutput not producing Chunked output on browser

gschandok
I have done it using
"httpHeaders.putSingle("Transfer-Encoding", "chunked");"

in the writeTo() method of custom MessageBodyWriter<ChunkedOutput<String>>