Search code examples
javarestglassfishapache-httpclient-4.xpayara

Timeout submitting a rest post with httpClient and Glassfish


I have an httpClient that send a json object and a set of file in the body The REST WS is a glassfish (payara) server When the file are little (not beyond 1k) it's working well When I send a request with a file larger than the others (I tried with ~130k and ~50k file) it throws an error at multipartStream.readBodyData(os); of the following function

public static String parseMultipart(InputStream stream, List<UploadedFile> uploadedFiles) throws IOException {

    String msgInfo = null;

    MultipartStream multipartStream = new MultipartStream(stream, "".getBytes());
    boolean nextPart = multipartStream.skipPreamble();

    if (nextPart) {

        // Information
        multipartStream.readHeaders();

        ByteArrayOutputStream os = new ByteArrayOutputStream();
        multipartStream.readBodyData(os);
       //json part
        msgInfo = new String(os.toByteArray(), java.nio.charset.StandardCharsets.UTF_8);

        nextPart = multipartStream.readBoundary();
    }

    // Files
    while (nextPart) {

        String header = multipartStream.readHeaders();
        String fileName = null;

        int fileNameStart = header.indexOf("filename=\"");
        int fileNameEnd = -1;
        if (fileNameStart != -1) {

            fileNameEnd = header.indexOf("\"", fileNameStart + 10);
            if (fileNameEnd != -1) {
                fileName = header.substring(fileNameStart + 10, fileNameEnd);
            }
        }

        if (fileName != null) {

            // Reads the body - Actual file data
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            multipartStream.readBodyData(os);

            if (os.size() > 0) {
                UploadedFile uploadedFile = new ByteArrayUploadedFile(os.toByteArray(), fileName, "");
                uploadedFiles.add(uploadedFile);
            } else {

                return null;
            }

        } else {
            return null;
        }

        nextPart = multipartStream.readBoundary();
    }

    return msgInfo;

The error is

Warning:   StandardWrapperValve[webServices.ApplicationConfig]: Servlet.service() for servlet webServices.ApplicationConfig threw exception
java.util.concurrent.TimeoutException
    at org.glassfish.grizzly.nio.tmpselectors.TemporarySelectorReader.read(TemporarySelectorReader.java:126)
    at org.glassfish.grizzly.nio.tmpselectors.TemporarySelectorReader.read(TemporarySelectorReader.java:75)
    at org.glassfish.grizzly.AbstractReader.read(AbstractReader.java:72)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransportFilter.handleRead(TCPNIOTransportFilter.java:77)
    at org.glassfish.grizzly.filterchain.TransportFilter.handleRead(TransportFilter.java:173)
    at org.glassfish.grizzly.ssl.SSLBaseFilter$SSLTransportFilterWrapper.handleRead(SSLBaseFilter.java:1132)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.read(DefaultFilterChain.java:352)
    at org.glassfish.grizzly.filterchain.FilterChainContext.read(FilterChainContext.java:736)
    at org.glassfish.grizzly.http.io.InputBuffer.blockingRead(InputBuffer.java:1103)
    at org.glassfish.grizzly.http.server.io.ServerInputBuffer.blockingRead(ServerInputBuffer.java:95)
    at org.glassfish.grizzly.http.io.InputBuffer.fill(InputBuffer.java:1127)
    at org.glassfish.grizzly.http.io.InputBuffer.read(InputBuffer.java:348)
    at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:273)
    at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:270)
    at org.glassfish.jersey.message.internal.EntityInputStream.read(EntityInputStream.java:102)
    at myapp.webServices.MultipartStream.readBodyData(MultipartStream.java:333)
    ...

The client part is with apache httpClient, the relevant part is

    request = new HttpPost(baseUrl + wsName);
    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addTextBody("info", restBag.getAsJsonObject().toString(), ContentType.APPLICATION_JSON);

    for (File file : restBag.getFileMap().values()) {
        builder.addBinaryBody("file", file, ContentType.APPLICATION_OCTET_STREAM, file.getName());
    }
    HttpEntity multipart = builder.build();
    request.setEntity(multipart);
response = httpClient.execute(request, localContext);

UPDATE

I've tried to change the REST method, using apache commons, but the result is the same

@POST
@Path("/send")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({"WS_Crea_Messaggio"})
public ReturnMessage sendMessage1(@Context HttpServletRequest httpRequest) throws IOException, JAXBException
{

    LOG.log(Level.FINEST, "User {0} called sendMessage", new Object[]{user});

    ReturnMessage ret = new ReturnMessage();
    String info = null;
    List<UploadedFile> uploadedFiles = new ArrayList<>();
    FileItemFactory factory = new DiskFileItemFactory();
    ServletFileUpload upload = new ServletFileUpload(factory);
// Parse the request
    Iterator /* FileItem */ items;
    try {
        items = upload.parseRequest(httpRequest).iterator();
while (items.hasNext()) {
    FileItem thisItem = (FileItem) items.next();
        if (thisItem.getFieldName().equals("info")) {
            info = thisItem.getString();
            // Do something with the value
    } else if (thisItem.getFieldName().equals("file")) {
        uploadedFiles.add(new ByteArrayUploadedFile(thisItem.get(), thisItem.getName(), thisItem.getContentType()));
    }

}
    }
    catch (FileUploadException ex) {
        LOG.log(Level.INFO, "Erroro uploading messages", ex);
        ret.setStatus(ReturnStatusEnum.ERROR);
        ret.setErrorCode(ReturnErrorCodeEnum.FILE_NOT_UPLOADED);
        return ret;
    }
....
}

No luck, again stop items = upload.parseRequest(httpRequest).iterator(); waiting for timeout

org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. java.util.concurrent.TimeoutException
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:371)
at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)
at myapp.webServices.MessagesWebService.sendMessage1(MessagesWebService.java:331)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4762)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:834)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:64)
at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52)
at sun.reflect.GeneratedMethodAccessor147.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:834)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:140)
at sun.reflect.GeneratedMethodAccessor149.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:834)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:374)
at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4734)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4722)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
at com.sun.proxy.$Proxy450.sendMessage1(Unknown Source)
at myapp.webServices.__EJB31_Generated__MessagesWebService__Intf____Bean__.sendMessage1(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:205)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
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:305)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1693)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
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:416)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:466)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:169)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:526)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: java.util.concurrent.TimeoutException
at org.glassfish.grizzly.nio.transport.TCPNIOTransportFilter.handleRead(TCPNIOTransportFilter.java:90)
at org.glassfish.grizzly.filterchain.TransportFilter.handleRead(TransportFilter.java:173)
at org.glassfish.grizzly.ssl.SSLBaseFilter$SSLTransportFilterWrapper.handleRead(SSLBaseFilter.java:1132)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.read(DefaultFilterChain.java:352)
at org.glassfish.grizzly.filterchain.FilterChainContext.read(FilterChainContext.java:736)
at org.glassfish.grizzly.http.io.InputBuffer.blockingRead(InputBuffer.java:1103)
at org.glassfish.grizzly.http.server.io.ServerInputBuffer.blockingRead(ServerInputBuffer.java:95)
at org.glassfish.grizzly.http.io.InputBuffer.fill(InputBuffer.java:1127)
at org.glassfish.grizzly.http.io.InputBuffer.read(InputBuffer.java:348)
at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:273)
at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:270)
at org.apache.commons.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:976)
at org.apache.commons.fileupload.MultipartStream$ItemInputStream.read(MultipartStream.java:886)
at java.io.InputStream.read(InputStream.java:101)
at org.apache.commons.fileupload.util.Streams.copy(Streams.java:96)
at org.apache.commons.fileupload.util.Streams.copy(Streams.java:66)
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:366)
... 88 more
Caused by: java.util.concurrent.TimeoutException
at org.glassfish.grizzly.nio.tmpselectors.TemporarySelectorReader.read(TemporarySelectorReader.java:126)
at org.glassfish.grizzly.nio.tmpselectors.TemporarySelectorReader.read(TemporarySelectorReader.java:75)
at org.glassfish.grizzly.AbstractReader.read(AbstractReader.java:72)
at org.glassfish.grizzly.nio.transport.TCPNIOTransportFilter.handleRead(TCPNIOTransportFilter.java:77)
... 107 more

I've tested it using both client and server on the same machine, but I have also tried with a remote client on the same subnet


Solution

  • The problem is related to the auth method I'm using. I'm accessing the application with client certificate and basic auth Disabling the certificate part the request is received till the end, with no problem I'll opening a new question to dig how to solve the problem, cause I need the client cert auth