1

I've read that it is possible to get primefaces fileUpload to work with google appengine with a bit of tweaking. It requires apache fileupload and common io, so I added commons-fileupload-1.2.2.jar and commons-io-1.3.2.jar to my WEB-INF/lib folder.

Then following the instructions of primefaces, I added their servlet:

<filter>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
    <init-param>
        <param-name>thresholdSize</param-name>
        <param-value>2147483647</param-value>
    </init-param>       
</filter>
<filter-mapping>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>  

The thresholdSize is put purposefully high because it is the number of bytes by which the file will be saved to disk rather than retain it in memory, and since no files can be saved using google appengine, it can never be an option.

The actual usage is as follows:

<h:form enctype="multipart/form-data">
    <!-- Other text fields go here -->
    <p:fileUpload fileUploadListener="#{tjBean.onHandleFileUpload}"  
        mode="advanced"  
        update=":toolbarForm:globalMessages"  
        sizeLimit="500000"   
        allowTypes="/(\.|\/)(txml)$/" /> 
<p:commandButton value="Okay" ajax="false" actionListener="#{tjBean.onSaveAction}" />
</h:form>

I've understood that the commandButton must not use ajax and that it must be a full page reload. It seems to let me upload the file without a hitch, but the actionListener never gets triggered. Submitting then the form with the commandButton triggers an exception:

java.lang.NoClassDefFoundError: Could not initialize class org.apache.commons.fileupload.disk.DiskFileItem
    at org.apache.commons.fileupload.disk.DiskFileItemFactory.createItem(DiskFileItemFactory.java:199)
    at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:361)
...

I'm not sure what I'm doing something wrong or I simply did not get the appropriate versions of the apache libraries to make this work properly. The version of primefaces that I'm using is 3.2. When I search for a solution to this problem, the common response is that google appengine doesn't like the fact that I'm trying to save a file to the disk, and the solution is simply to increase the threshold, but the threshold is as high as it can be, so it shouldn't even be attempting to save the file to disk.

I'd appreciate any help or suggestions, especially if the solution is glaringly obvious and I have yet to see it. Thanks in advance.

Neil
  • 5,762
  • 24
  • 36

3 Answers3

1

Neil, you can't write to the disk (i.e. you can't use fileupload.disk on GAE).

App Engine filesystem is always read-only for you app. A couple alternatives you might consider are:

Also, check out this one: http://primefaces-rocks.appspot.com/ui/fileUploadSimple.jsf

alex
  • 2,450
  • 16
  • 22
  • Why did I read that it was possible then? You positive about that? – Neil Apr 08 '12 at 19:27
  • Here is the [link](http://davebarber.blog.com/2010/10/15/jsf-2-0-on-google-app-engine/) you requested. – Neil Apr 08 '12 at 19:41
  • Well, commons-io-1.3.2.jar needs to be recompiled from the sources, just like the guy says: remove `java.rmi.server.UID` from `org.apache.commons.fileupload.disk.DiskFileItem` and recompile the whole thing (commons-io-1.3.2.jar). I would not recommend this approach, though, as you'll always have to keep up with commons-io and related libraries updates and recompile them yourself. Also, it can easily happen that a next version of commons-io will be using some other classes, in a different way, that will not allow the library to function on GAE at all. – alex Apr 08 '12 at 19:49
  • None of your solutions allow me to continue using primefaces or jsf, not without some serious hacking. Though not that recompiling the entire library wouldn't be hacky. Anyway, I appreciate the effort. – Neil Apr 08 '12 at 20:10
1

Fixed the problem by overriding DiskItem for Apache fileupload library 1.2.2.

Specifically, commented static String UID (which uses blacklisted class java.rmi.server.UID) and entire contents of write method (I'll set threshold high so it should never require to call it).

Obviously it's not the ideal solution, but it will work so long as I don't need to update file upload library, which I doubt I'll need to in the near future.

Neil
  • 5,762
  • 24
  • 36
  • Anyone care to comment as to why they marked this down? I didn't have to share my solution, but I am for anyone to see who's in a similar situation. It may not be ideal, but it's the best solution thus far. – Neil Apr 10 '12 at 12:18
1

@Neil

I'm sorry but I cannot comment. Can you tell me how you change the method

getTempFile() {
        if (tempFile == null) {
            File tempDir = repository;
            if (tempDir == null) {
                tempDir = new File(System.getProperty("java.io.tmpdir"));
            }

            String tempFileName = format("upload_%s_%s.tmp", UID, getUniqueId());

            tempFile = new File(tempDir, tempFileName);
        }
        return tempFile;
    }

What did you use instead of UID?

makkasi
  • 6,328
  • 4
  • 45
  • 60
  • 1
    I don't recall what I did exactly. It has been some time since I made the fix, but unless things have changed, everything pertaining to the UID isn't necessary for what I used it for. Therefore, you could probably get away with putting any value there or nothing at all. – Neil Jan 29 '14 at 13:17