Grails: Tomcat File Upload Woes

Things aren't always groovy in the Grails world.  Grails makes an effort to support many disparate application servers.  Sometimes this all encompassing approach can lead to problems.  This is a "Grails gotcha" I recently ran into.

I'm currently working on an application that requires users to upload files to the server.  Thanks to some good documentation, I was able to get this up and running  quite easily, or so I thought.

In my development environment, which by default utilizes Jetty, everthing ran fine.  The problem didn't appear until I tested the application on Tomcat 6.0.18 which we'll be using in production.  My form code was as follows:

<g:form id="receiptUpload" controller="expenseReport" action="upload" id="${expenseReportId}" method="post" enctype="multipart/form-data">
    <table width="100">
        <tbody>
            <tr>
                <td><label>File:</label></td>
                <td><input type="file" name="image" class="is_required"/></td>
            </tr>
            <tr>
                <td>&nbsp;</td>

                <td class="validFileTypes">
                    jpeg, bmp, png, pnm, tiff, wbmp
                </td>

            </tr>
            <tr>
                <td/>
                <td><input type="submit" value="Upload"/>
                </td>
            </tr>
        </tbody>
    </table>
</g:form>

When the user attempted to upload a file, they were greeted with the following error:

Could not find closure property for URI [/expenseReport/upload/1] for controller [ExpenseReportController]!

Can you spot the cause of the problem?  Initially it's not that obvious.  When I tried to access the controller directly by typing it in the URL, the controller and the closure seemed to be found.  Everything appeared to be coded properly.  Hmmm...dilemmas, dilemmas.

I deployed the same application on Glassfish and it worked!  Okay, the problem was a Tomcat one, but what was the cause?  After some trial and error I found the culprit.  Tomcat does not like it when you include the id attribute in the <g:form> tag!  Notice the url in the error message: "/expenseReport/upload/1".  That URL is formatted improperly for Tomcat.  It should be: "/expenseReport/upload?id=1"

Modifying my form to pass the id in as a hidden field did the trick.  Here's the correct form with modified lines in bold text:

<g:form controller="expenseReport" action="upload" method="post" enctype="multipart/form-data">
    <table width="100">
        <tbody>
            <tr>
                <td><label>File:</label></td>
                <td><input type="file" name="image" class="is_required"/></td>
            </tr>
            <tr>
                <td>&nbsp;</td>
                <td class="validFileTypes">
                    jpeg, bmp, png, pnm, tiff, wbmp
                    <input type="hidden" name="id" value="${expenseReportId}" />
                </td>
            </tr>
            <tr>
                <td/>
                <td><input type="submit" value="Upload"/>
                </td>
            </tr>
        </tbody>
    </table>
</g:form>

Tomcat only choked on the id attribute during file uploads.  It worked as expected in all other scenarios.  In summary, don't use the id attributed in <g:form> tags if you plan on doing any file uploading.  It will only get you into trouble.

Comments:

Good Detective Work

by Ed.T on February 24, 2009 at 12:06 PM CST
Good job tracking that one down. I appreciate that you documented it here so others can see what you have discovered. Personally, I am enjoying hosting on Glassfish.

Two id attributes in the first form

by JK on February 24, 2009 at 2:51 PM CST
Hi, thanks for sharing. In the first form you have two id attributes in your g:form tag: id="receiptUpload" and id="${expenseReportId}" Maybe it has also something to do with that Greetings, Juri

Two id attributes

by Dean Del Ponte on February 24, 2009 at 8:43 PM CST
JK - Great catch on the two id attributes. Removing one of the id attributes still results in the same error.

Send this bug to grails team

by Dunsun on February 25, 2009 at 9:26 AM CST
Hey, I guess you should put this bug into grails JIRA buglist. I know this bug is tomcat related only but ....

Mr

by Dave on February 26, 2009 at 3:01 AM CST
form code is the same in both places... at least the "bold code" in the second also appears on the first... O:)

Duplicate Form Code Corrected

by Dean Del Ponte on February 26, 2009 at 9:41 AM CST
Thanks 'Mr'. The form code has been modified. I need to be a bit more careful when performing copy/paste!
Subject*
Name*
Comment*