0
votes

I am using Mojarra 2.2.0 and tomahawk12-1.1.14 (t:inputFileUpload) in a Google App Engine project (api-1.0-sdk-1.8.4) using Eclipse Kepler.

The project works perfectly when running locally from Eclipse, but I get the following error if deployed to Google App Engine when trying to upload a file:

/faces/tmotifs.xhtml
java.lang.NullPointerException
    at java.io.File.<init>(File.java:290)
    at org.apache.myfaces.webapp.filter.MultipartRequestWrapper.parseRequest(MultipartRequestWrapper.java:141)
    at org.apache.myfaces.webapp.filter.MultipartRequestWrapper.getParameter(MultipartRequestWrapper.java:299)
    at com.sun.faces.context.RequestParameterMap.get(RequestParameterMap.java:75)
    at com.sun.faces.context.RequestParameterMap.get(RequestParameterMap.java:56)
    at java.util.Collections$UnmodifiableMap.get(Collections.java:1339)
    ...

I use the file upload component in tmotifs.xhtml like this:

<h:form enctype="multipart/form-data">
    <t:inputFileUpload value="#{trainingBean.uploadedFile}"
        accept="text/x-fasta" requiredMessage="A fasta file must be selected" />
    <h:commandButton value="Refresh" actionListener="#{trainingBean.upload}" />
....

The backing bean looks like this:

@ManagedBean
@SessionScoped
public class TrainingBean implements Serializable {
    private static final long serialVersionUID = 1L;
    private UploadedFile uploadedFile;

    public UploadedFile getUploadedFile() {
        return uploadedFile;
    }

    public void setUploadedFile(UploadedFile uploadedFile) {
        this.uploadedFile = uploadedFile;
    }

    public void upload() {
        if( uploadedFile == null ) {
            refresh();
            return;
        }

        this.inputList.clear();
        try {
            Reader rd = new InputStreamReader(uploadedFile.getInputStream());
            inputGroupList = InputGroup.readEntries(rd); 
            rd.close();
            for( InputGroup p : inputGroupList )
                this.inputList.addAll(p.getMotifs());
            uploadError = null;
            inputFileName = uploadedFile.getName();
        } catch (IOException e) {
            uploadError = e.getMessage();
            e.printStackTrace();
        } catch( InvalidSequenceException e ) {
            uploadError = e.getMessage();
            e.printStackTrace();
        }

        refresh();
    }
...

And the web.xml:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<web-app
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    version="2.5"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>JavaServerFaces</display-name>    

    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <!--<param-value>client</param-value>-->
        <param-value>server</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
        <param-value>.xhtml</param-value>
    </context-param>
    <context-param>  
        <param-name>com.sun.faces.expressionFactory</param-name>  
        <param-value>com.sun.el.ExpressionFactoryImpl</param-value>  
    </context-param>
    <!-- Disable use of threading for single-threaded environments such as the Google AppEngine. -->
    <context-param>
        <param-name>com.sun.faces.enableThreading</param-name>
        <param-value>false</param-value>
    </context-param>    
    <!-- Change to "Production" when you are ready to deploy -->
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
        <param-value>true</param-value>
    </context-param>

    <!-- ***** Specify session timeout of thirty (30) minutes. ***** -->
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

    <!-- Welcome page -->
    <welcome-file-list>
        <welcome-file>faces/home.xhtml</welcome-file>
    </welcome-file-list>

    <!-- JSF mapping -->
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
        <url-pattern>*.jsf</url-pattern>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

    <!-- MyFaces Tomahawk -->
    <filter>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
        <init-param>
            <param-name>uploadMaxFileSize</param-name>
            <param-value>20m</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>
    <filter-mapping>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <url-pattern>/faces/myFacesExtensionResource/*</url-pattern>
    </filter-mapping>

    <error-page>
        <exception-type>javax.faces.application.ViewExpiredException</exception-type>
        <location>/faces/home.xhtml</location>
    </error-page>

    <!-- System -->
    <servlet>
        <servlet-name>SystemServiceServlet</servlet-name>
        <servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
        <init-param>
            <param-name>services</param-name>
            <param-value/>
        </init-param>
    </servlet>  
    <servlet-mapping>
        <servlet-name>SystemServiceServlet</servlet-name>
        <url-pattern>/_ah/spi/*</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>es.ehu.grk.wregex.gae.ServletListener</listener-class>
    </listener>
</web-app>

So my question is, am I missing something? why t:inputFileUpload works fine when running in the local GAE server but not when deploying?

Any help/directions would be wellcome. Thank you in advance!

1
Great that you have solved it, but you shouldn't post the answer inside the question. Instead, post the answer as a real answer. Then you can mark it accepted and then the question will appear in the listing as "solved" without the need to clutter the title for that.BalusC
OK, didn't know about that policy! I will change it now! Thanksakrog
Great. Stack Overflow is a Question & Answer site, not a discussion forum. That's why :) Answers are therefore also much easier to find here.BalusC

1 Answers

1
votes

Finally I solved the problem by using fileUpload from PrimeFaces in advanced mode (simple file upload did not work) following the instructions on JSF file upload on GAE, but instead of using BlobUtils (now deprecated?) in the backing bean I read the file from memory as:

public void uploadedFileEvent(FileUploadEvent event) {
    Reader rd = new InputStreamReader(new ByteArrayInputStream(event.getFile().getContents()));
    //...
}