Hello Joakim,

Thanks for the clarification - the old version of our application was written 
using Grails 1.3.9, which was based on Spring MVC 3.0.x rather than Spring 
Boot, but I can confirm that it ran on Jetty 8.1.14. 

The file upload functionality was provided by the Spring MultipartFile 
interface, which is implemented using Commons File Upload - for some reason, 
this worked with Jetty 8.x but fails with Jetty 9.x.

Best wishes,

Robert

> On 27 Feb 2018, at 18:32, Joakim Erdfelt <[email protected]> wrote:
> 
> Jetty 8.1 is Servlet 3.0, not Servlet 2.5.
> 
> If you used a spring boot that was for Servlet 2.5 on Jetty 8.1 then you'd 
> have Servlet 2.5 support and expectations (eg: it wouldn't know about 
> Part.write(String))
> 
> The Jetty 8.1 / Servlet 3.0 behavior of Part.write(String) is the same as it 
> is in Jetty 9.x and Servlet 3.1
> 
> 
> Joakim Erdfelt / [email protected] <mailto:[email protected]>
> On Tue, Feb 27, 2018 at 12:08 PM, Robert Stroud <[email protected] 
> <mailto:[email protected]>> wrote:
> Hello Joakim,
> 
> One further question about the file upload issue - we previously used Jetty 
> Runner version 8.x to launch our application and the file upload feature 
> worked correctly. 
> 
> Can you clarify whether the earlier version of Jetty Runner behaved 
> differently with respect to file uploads - for example, it presumably 
> implemented the Servlet 2.5 specification rather than than Servlet 3.0 
> specification, but I don’t know if this would make any difference? 
> 
> Also, to clarify something in my earlier email, I said that the problem had 
> been fixed in Spring 5.0 but not back ported to Spring 4.3.9. In fact, the 
> patch was applied to Spring 4.3.8, but I believe it doesn’t fix the problem.
> 
> Thanks again for your help with this issue.
> 
> Best wishes,
> 
> Robert
> 
>> On 27 Feb 2018, at 10:39, Robert Stroud <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> Hello Joakim,
>> 
>> Thank you for the additional explanation - the difference between the Tomcat 
>> behaviour and the official behaviour is the underlying cause of our problem.
>> 
>> Apparently, the Spring MultipartFile abstraction has always allowed files to 
>> be uploaded to an absolute path location, but assumed that the underlying 
>> Servlet Container behaved like Tomcat:
>> 
>> https://jira.spring.io/browse/SPR-15257#comment-135998 
>> <https://jira.spring.io/browse/SPR-15257#comment-135998>
>> 
>> This has apparently been fixed in Spring 5.0 but doesn’t seem to have been 
>> back ported to Spring 4.3.9, which is the version we are using.
>> 
>> Best wishes,
>> 
>> Robert
>> 
>> 
>> 
>> 
>> 
>>> [email protected] <mailto:[email protected]>> wrote:
>>> 
>>> Tomcat implemented their version based on commons-fileupload, and an early 
>>> version of their own javadoc for the servlet spec.
>>> 
>>> See: 
>>> https://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/http/Part.html#write(java.lang.String)
>>>  
>>> <https://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/http/Part.html#write(java.lang.String)>
>>> 
>>> > fileName - The location into which the uploaded part should be stored. 
>>> > Relative locations are relative to MultipartConfigElement.getLocation()
>>> 
>>> vs
>>> 
>>> https://docs.oracle.com/javaee/7/api/javax/servlet/http/Part.html#write-java.lang.String-
>>>  
>>> <https://docs.oracle.com/javaee/7/api/javax/servlet/http/Part.html#write-java.lang.String->
>>> 
>>> > fileName - the name of the file to which the stream will be written. The 
>>> > file is created relative to the location as specified in the 
>>> > MultipartConfig
>>> 
>>> Notice the difference in documentation?
>>> The Tomcat implementation isn't based on the actual final Servlet 3.0 spec.
>>> 
>>> 
>>> Joakim Erdfelt / [email protected] <mailto:[email protected]>
>>> On Mon, Feb 26, 2018 at 12:23 PM, Robert Stroud <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> Hello Joakim,
>>> 
>>> Thank you for your quick response to my question - it sounds as though the 
>>> root of our problem is an ambiguity or difference in interpretation of the 
>>> servlet specification.
>>> 
>>>> I bet your configuration has MultipartConfig.location set to 
>>>> java.io.tmpdir (the default value), hence why your transferTo() is 
>>>> prefixed with "/tmp"
>>> 
>>> 
>>> That sounds like a good bet to me… :-)
>>> 
>>> Best wishes,
>>> 
>>> Robert
>>> 
>>> 
>>>> On 26 Feb 2018, at 17:49, Joakim Erdfelt <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>> 
>>>> Some more background/detail on this ...
>>>> 
>>>> Interestingly page 224 of the Servlet 4.0 metions this ..
>>>> 
>>>> https://javaee.github.io/servlet-spec/downloads/servlet-4.0/servlet-4_0_FINAL.pdf
>>>>  
>>>> <https://javaee.github.io/servlet-spec/downloads/servlet-4.0/servlet-4_0_FINAL.pdf>
>>>> 
>>>> 21. Clarify interpretation of fileName parameter for method Part.write(). 
>>>> See the javadoc for details.
>>>> 
>>>> Found the issue for Part.write at ...
>>>> 
>>>> https://github.com/javaee/servlet-spec/issues/172 
>>>> <https://github.com/javaee/servlet-spec/issues/172>
>>>> 
>>>> Finally a link to Part.write in the Servlet 4.0 Part.write update ...
>>>> 
>>>> https://github.com/javaee/servlet-spec/blob/4.0.0/src/main/java/javax/servlet/http/Part.java#L93-L113
>>>>  
>>>> <https://github.com/javaee/servlet-spec/blob/4.0.0/src/main/java/javax/servlet/http/Part.java#L93-L113>
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> Joakim Erdfelt / [email protected] <mailto:[email protected]>
>>>> On Mon, Feb 26, 2018 at 11:31 AM, Joakim Erdfelt <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>> You should never assume that Part.write() or .transferTo() accepts fully 
>>>> qualified locations on disk, its always relative to the 
>>>> MultipartConfig.location.
>>>> 
>>>> See:
>>>> https://github.com/eclipse/jetty.project/issues/1337 
>>>> <https://github.com/eclipse/jetty.project/issues/1337>
>>>> https://docs.oracle.com/javaee/7/api/javax/servlet/http/Part.html 
>>>> <https://docs.oracle.com/javaee/7/api/javax/servlet/http/Part.html>
>>>> https://docs.oracle.com/javaee/7/api/javax/servlet/http/Part.html#write-java.lang.String-
>>>>  
>>>> <https://docs.oracle.com/javaee/7/api/javax/servlet/http/Part.html#write-java.lang.String->
>>>>  
>>>> 
>>>> The Apache Commons File Upload package (last time I looked) will delegate 
>>>> to the servlet spec HttpServletRequest.getPart() behavior.
>>>> Since Tomcat's Part.write(String) allows you to write to any arbitrary 
>>>> location on disk that's how Apache Commons File Upload expects it.
>>>> 
>>>> The javadoc for Part.write() says it will write relative to the 
>>>> MultipartConfig.location.
>>>> 
>>>> I bet your configuration has MultipartConfig.location set to 
>>>> java.io.tmpdir (the default value), hence why your transferTo() is 
>>>> prefixed with "/tmp"
>>>> 
>>>> This was brought up in the Servlet spec 4.0 discussions (not sure how it 
>>>> was resolved)
>>>> 
>>>> 
>>>> Joakim Erdfelt / [email protected] <mailto:[email protected]>
>>>> 
>>>> On Mon, Feb 26, 2018 at 11:17 AM, Robert Stroud <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>> Hello,
>>>> 
>>>> We are using Jetty Runner 9.4.8 to launch a Java web application from a 
>>>> WAR file and have encountered a problem with file uploads. The code in 
>>>> question works fine if the WAR file is launched by Tomcat, but fails if 
>>>> the WAR file is launched by Jetty Runner, which suggests that there may be 
>>>> a problem with the way in which we have configured Jetty Runner.
>>>> 
>>>> The application is written in Grails, which runs on Spring Boot, so we are 
>>>> using the Spring MultipartFile interface to upload the file. At the point 
>>>> at which the web application attempts to store a copy of the uploaded file 
>>>> in a local folder on the web server, we get a  “File not found exception”. 
>>>> This appears to be caused by the value of “java.io.tmpdir” being prepended 
>>>> to the target filename, which means that the path is invalid. Can anyone 
>>>> suggest why this might be happening?
>>>> 
>>>> In more detail, the relevant line of code is
>>>> 
>>>>         uploader.transferTo(“/some/destination”)        // make a local 
>>>> copy of the file upload
>>>> 
>>>> and the exception is
>>>> 
>>>>         java.io.FileNotFoundException: /tmp/some/destination/file (No such 
>>>> file of directory)
>>>> 
>>>> Note that “/tmp” (or more precisely, the value of 
>>>> System.getProperty(“java.io <http://java.io/>.tmpdir”)) has been prepended 
>>>> to the destination pathname, which makes it invalid.
>>>> 
>>>> The problem seems to be with the implementation of the Spring 
>>>> MultipartFile interface on Jetty Launcher - I believe Spring Boot is using 
>>>> an implementation based on the Apache Commons File Upload package. Does 
>>>> anyone know of a reason why this might not work on Jetty?
>>>> 
>>>> Thanks for any help or suggestions.
>>>> 
>>>> Best wishes,
>>>> 
>>>> Robert
>>>> 
>>>> _______________________________________________
>>>> jetty-users mailing list
>>>> [email protected] <mailto:[email protected]>
>>>> To change your delivery options, retrieve your password, or unsubscribe 
>>>> from this list, visit
>>>> https://dev.eclipse.org/mailman/listinfo/jetty-users 
>>>> <https://dev.eclipse.org/mailman/listinfo/jetty-users>
>>>> 
>>>> _______________________________________________
>>>> jetty-users mailing list
>>>> [email protected] <mailto:[email protected]>
>>>> To change your delivery options, retrieve your password, or unsubscribe 
>>>> from this list, visit
>>>> https://dev.eclipse.org/mailman/listinfo/jetty-users 
>>>> <https://dev.eclipse.org/mailman/listinfo/jetty-users>
>>> 
>>> _______________________________________________
>>> jetty-users mailing list
>>> [email protected] <mailto:[email protected]>
>>> To change your delivery options, retrieve your password, or unsubscribe 
>>> from this list, visit
>>> https://dev.eclipse.org/mailman/listinfo/jetty-users 
>>> <https://dev.eclipse.org/mailman/listinfo/jetty-users>
>>> 
>>> _______________________________________________
>>> jetty-users mailing list
>>> [email protected] <mailto:[email protected]>
>>> To change your delivery options, retrieve your password, or unsubscribe 
>>> from this list, visit
>>> https://dev.eclipse.org/mailman/listinfo/jetty-users 
>>> <https://dev.eclipse.org/mailman/listinfo/jetty-users>
> 
> 
> _______________________________________________
> jetty-users mailing list
> [email protected] <mailto:[email protected]>
> To change your delivery options, retrieve your password, or unsubscribe from 
> this list, visit
> https://dev.eclipse.org/mailman/listinfo/jetty-users 
> <https://dev.eclipse.org/mailman/listinfo/jetty-users>
> 
> _______________________________________________
> jetty-users mailing list
> [email protected]
> To change your delivery options, retrieve your password, or unsubscribe from 
> this list, visit
> https://dev.eclipse.org/mailman/listinfo/jetty-users

_______________________________________________
jetty-users mailing list
[email protected]
To change your delivery options, retrieve your password, or unsubscribe from 
this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users

Reply via email to