Problem with file uploads for Jetty Runner

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Problem with file uploads for Jetty Runner

Robert Stroud
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.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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users
Reply | Threaded
Open this post in threaded view
|

Re: Problem with file uploads for Jetty Runner

Joakim Erdfelt-8
You should never assume that Part.write() or .transferTo() accepts fully qualified locations on disk, its always relative to the MultipartConfig.location.

See:
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 / [hidden email]

On Mon, Feb 26, 2018 at 11:17 AM, Robert Stroud <[hidden email]> 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.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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users
Reply | Threaded
Open this post in threaded view
|

Re: Problem with file uploads for Jetty Runner

Joakim Erdfelt-8
Some more background/detail on this ...

Interestingly page 224 of the Servlet 4.0 metions this ..


21. Clarify interpretation of fileName parameter for method Part.write(). See the javadoc for details.

Found the issue for Part.write at ...


Finally a link to Part.write in the Servlet 4.0 Part.write update ...






Joakim Erdfelt / [hidden email]

On Mon, Feb 26, 2018 at 11:31 AM, Joakim Erdfelt <[hidden email]> wrote:
You should never assume that Part.write() or .transferTo() accepts fully qualified locations on disk, its always relative to the MultipartConfig.location.

See:
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 / [hidden email]

On Mon, Feb 26, 2018 at 11:17 AM, Robert Stroud <[hidden email]> 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.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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users
Reply | Threaded
Open this post in threaded view
|

Re: Problem with file uploads for Jetty Runner

Robert Stroud
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 <[hidden email]> wrote:

Some more background/detail on this ...

Interestingly page 224 of the Servlet 4.0 metions this ..


21. Clarify interpretation of fileName parameter for method Part.write(). See the javadoc for details.

Found the issue for Part.write at ...


Finally a link to Part.write in the Servlet 4.0 Part.write update ...






Joakim Erdfelt / [hidden email]

On Mon, Feb 26, 2018 at 11:31 AM, Joakim Erdfelt <[hidden email]> wrote:
You should never assume that Part.write() or .transferTo() accepts fully qualified locations on disk, its always relative to the MultipartConfig.location.

See:
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 / [hidden email]

On Mon, Feb 26, 2018 at 11:17 AM, Robert Stroud <[hidden email]> 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.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
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users
Reply | Threaded
Open this post in threaded view
|

Re: Problem with file uploads for Jetty Runner

Joakim Erdfelt-8
Tomcat implemented their version based on commons-fileupload, and an early version of their own javadoc for the servlet spec.


> fileName - The location into which the uploaded part should be stored. Relative locations are relative to MultipartConfigElement.getLocation()

vs


> 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 / [hidden email]

On Mon, Feb 26, 2018 at 12:23 PM, Robert Stroud <[hidden email]> 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 <[hidden email]> wrote:

Some more background/detail on this ...

Interestingly page 224 of the Servlet 4.0 metions this ..


21. Clarify interpretation of fileName parameter for method Part.write(). See the javadoc for details.

Found the issue for Part.write at ...


Finally a link to Part.write in the Servlet 4.0 Part.write update ...






Joakim Erdfelt / [hidden email]

On Mon, Feb 26, 2018 at 11:31 AM, Joakim Erdfelt <[hidden email]> wrote:
You should never assume that Part.write() or .transferTo() accepts fully qualified locations on disk, its always relative to the MultipartConfig.location.

See:
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 / [hidden email]

On Mon, Feb 26, 2018 at 11:17 AM, Robert Stroud <[hidden email]> 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.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
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users
Reply | Threaded
Open this post in threaded view
|

Re: Problem with file uploads for Jetty Runner

Robert Stroud
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:


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





Reading[hidden email]> wrote:

Tomcat implemented their version based on commons-fileupload, and an early version of their own javadoc for the servlet spec.


> fileName - The location into which the uploaded part should be stored. Relative locations are relative to MultipartConfigElement.getLocation()

vs


> 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 / [hidden email]

On Mon, Feb 26, 2018 at 12:23 PM, Robert Stroud <[hidden email]> 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 <[hidden email]> wrote:

Some more background/detail on this ...

Interestingly page 224 of the Servlet 4.0 metions this ..


21. Clarify interpretation of fileName parameter for method Part.write(). See the javadoc for details.

Found the issue for Part.write at ...


Finally a link to Part.write in the Servlet 4.0 Part.write update ...






Joakim Erdfelt / [hidden email]

On Mon, Feb 26, 2018 at 11:31 AM, Joakim Erdfelt <[hidden email]> wrote:
You should never assume that Part.write() or .transferTo() accepts fully qualified locations on disk, its always relative to the MultipartConfig.location.

See:
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 / [hidden email]

On Mon, Feb 26, 2018 at 11:17 AM, Robert Stroud <[hidden email]> 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.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
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users
Reply | Threaded
Open this post in threaded view
|

Re: Problem with file uploads for Jetty Runner

Robert Stroud
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 <[hidden email]> 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:


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





Reading[hidden email]> wrote:

Tomcat implemented their version based on commons-fileupload, and an early version of their own javadoc for the servlet spec.


> fileName - The location into which the uploaded part should be stored. Relative locations are relative to MultipartConfigElement.getLocation()

vs


> 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 / [hidden email]

On Mon, Feb 26, 2018 at 12:23 PM, Robert Stroud <[hidden email]> 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 <[hidden email]> wrote:

Some more background/detail on this ...

Interestingly page 224 of the Servlet 4.0 metions this ..


21. Clarify interpretation of fileName parameter for method Part.write(). See the javadoc for details.

Found the issue for Part.write at ...


Finally a link to Part.write in the Servlet 4.0 Part.write update ...






Joakim Erdfelt / [hidden email]

On Mon, Feb 26, 2018 at 11:31 AM, Joakim Erdfelt <[hidden email]> wrote:
You should never assume that Part.write() or .transferTo() accepts fully qualified locations on disk, its always relative to the MultipartConfig.location.

See:
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 / [hidden email]

On Mon, Feb 26, 2018 at 11:17 AM, Robert Stroud <[hidden email]> 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.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
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users
Reply | Threaded
Open this post in threaded view
|

Re: Problem with file uploads for Jetty Runner

Joakim Erdfelt-8
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 / [hidden email]

On Tue, Feb 27, 2018 at 12:08 PM, Robert Stroud <[hidden email]> 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 <[hidden email]> 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:


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





Reading[hidden email]> wrote:

Tomcat implemented their version based on commons-fileupload, and an early version of their own javadoc for the servlet spec.


> fileName - The location into which the uploaded part should be stored. Relative locations are relative to MultipartConfigElement.getLocation()

vs


> 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 / [hidden email]

On Mon, Feb 26, 2018 at 12:23 PM, Robert Stroud <[hidden email]> 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 <[hidden email]> wrote:

Some more background/detail on this ...

Interestingly page 224 of the Servlet 4.0 metions this ..


21. Clarify interpretation of fileName parameter for method Part.write(). See the javadoc for details.

Found the issue for Part.write at ...


Finally a link to Part.write in the Servlet 4.0 Part.write update ...






Joakim Erdfelt / [hidden email]

On Mon, Feb 26, 2018 at 11:31 AM, Joakim Erdfelt <[hidden email]> wrote:
You should never assume that Part.write() or .transferTo() accepts fully qualified locations on disk, its always relative to the MultipartConfig.location.

See:
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 / [hidden email]

On Mon, Feb 26, 2018 at 11:17 AM, Robert Stroud <[hidden email]> 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.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
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users
Reply | Threaded
Open this post in threaded view
|

Re: Problem with file uploads for Jetty Runner

Robert Stroud
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 <[hidden email]> 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 / [hidden email]

On Tue, Feb 27, 2018 at 12:08 PM, Robert Stroud <[hidden email]> 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 <[hidden email]> 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:


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





Reading[hidden email]> wrote:

Tomcat implemented their version based on commons-fileupload, and an early version of their own javadoc for the servlet spec.


> fileName - The location into which the uploaded part should be stored. Relative locations are relative to MultipartConfigElement.getLocation()

vs


> 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 / [hidden email]

On Mon, Feb 26, 2018 at 12:23 PM, Robert Stroud <[hidden email]> 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 <[hidden email]> wrote:

Some more background/detail on this ...

Interestingly page 224 of the Servlet 4.0 metions this ..


21. Clarify interpretation of fileName parameter for method Part.write(). See the javadoc for details.

Found the issue for Part.write at ...


Finally a link to Part.write in the Servlet 4.0 Part.write update ...






Joakim Erdfelt / [hidden email]

On Mon, Feb 26, 2018 at 11:31 AM, Joakim Erdfelt <[hidden email]> wrote:
You should never assume that Part.write() or .transferTo() accepts fully qualified locations on disk, its always relative to the MultipartConfig.location.

See:
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 / [hidden email]

On Mon, Feb 26, 2018 at 11:17 AM, Robert Stroud <[hidden email]> 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.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
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users