JSF 1.2 Rich File upload throwing IOException

339 Views Asked by At

I am trying to implement rich:fileUpload in a very old system using java8, JSF 1.2, RichFaces 3.3.3.Final, net.java.dev.ajax4jsf 1.0.6, on Glassfish 4.1. The system is massive so please don't ask me to update it, that will take 10 years :)

I have been hacking at it for many days now and keep running into a wall. Any help or guidance will be greatly appreciated.

When I open the web app I am able to select a file and click on upload, it then hangs there for a second or two and then fails. It never reaches my backing bean.

This is what I have so far: In my xhtml:

xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich

<h:form enctype="multipart/form-data">
   <rich:fileUpload fileUploadListener="#{fileUploadBean.fileUploadListener}"/>
</h:form>

In my web.xml:

  <filter>
    <display-name>RichFaces Filter</display-name>
    <filter-name>richfaces</filter-name>
    <filter-class>org.ajax4jsf.Filter</filter-class>
      <init-param>
          <param-name>createTempFiles</param-name>
          <param-value>false</param-value>
      </init-param>
  </filter>
  <filter-mapping>
    <filter-name>richfaces</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
  </filter-mapping>
  <filter>

In my FileUploadBean.java

@ManagedBean(name = "fileUploadBean")
@SessionScoped
public class FileUploadBean{

    public void fileUploadListener(UploadEvent uploadEvent) throws FileNotFoundException {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ServletContext servletContext = (ServletContext)facesContext.getExternalContext().getContext();
        String realTargetPath = servletContext.getRealPath("/");
        UploadItem uploadItem = uploadEvent.getUploadItem();
        String filePathname = uploadItem.getFileName();
        String fileName = "";
        System.out.println("STOP");
    }

When I try to upload a file I get:

enter image description here

The stack trace:

[2022-04-24T10:18:30.122+0200] [glassfish 4.1] [WARNING] [] [javax.enterprise.web] [tid: _ThreadID=72 _ThreadName=http-listener-1(2)] [timeMillis: 1650788310122] [levelValue: 900] [[
  StandardWrapperValve[Faces Servlet]: Servlet.service() for servlet Faces Servlet threw exception
org.ajax4jsf.exception.FileUploadException: IO Error parsing multipart request
    at org.ajax4jsf.request.MultipartRequest.getParam(MultipartRequest.java:556)
    at org.ajax4jsf.request.MultipartRequest.getParameter(MultipartRequest.java:616)
    at com.freesoft.http.FsSessionFilter.doFilter(FsSessionFilter.java:55)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:206)
    at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
    at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:367)
    at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
    at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:41002)
    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:415)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
    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:561)
    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:565)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: Request data cannot be read
    at org.ajax4jsf.request.MultipartRequest.readData(MultipartRequest.java:341)
    at org.ajax4jsf.request.MultipartRequest.readNext(MultipartRequest.java:210)
    at org.ajax4jsf.request.MultipartRequest.getParam(MultipartRequest.java:551)
    ... 38 more
]]
1

There are 1 best solutions below

2
Vasil Lukach On

Following code worked for me in RichFaces project years ago (it is from RichFaces 4, but I guess very similar been used in RichaFaces 3):

<h:form id="bannerSetupForm" enctype="multipart/form-data">
    <rich:fileUpload id="bannerUploader"
        fileUploadListener="#{retailerAction.bannerListener}"
        acceptedTypes="png, gif, jpg, jpeg"
        noDuplicate="true"
        ontyperejected="alert('#{msg.bannerFormatRestriction}');"
        maxFilesQuantity="1"
        addLabel="#{msg.bannerUploadAddButtonLabel}"
        uploadLabel="#{msg.bannerUploadUploadButtonLabel}">
        <a4j:ajax event="uploadcomplete" execute="@none"
            render="bannerPreviewPopup, bannerAccordionItem" />
    </rich:fileUpload>
</h:form>

But in my case upload parameters were set up in web.xml in different way:

<context-param>
    <param-name>org.richfaces.fileUpload.maxRequestSize</param-name>
    <param-value>524288</param-value>
</context-param>
<context-param>
    <param-name>org.richfaces.fileUpload.createTempFiles</param-name>
    <param-value>false</param-value>
</context-param>

Even if in majority of cases it is not necessary, you can add commons-fileupload-1.3.1.jar in lib folder of your application. Please check jar version, as for older RichFaces it could be lower.

And you can verify value of X-Frame-Options header here. Sometimes file upload does not work, if value of header is incorrect.