grails-aws icon indicating copy to clipboard operation
grails-aws copied to clipboard

No such property: s3upload for class: java.io.FileInputStream

Open bgrins opened this issue 12 years ago • 7 comments

Hi, thanks for the plugin. I'm having an issue getting the s3upload method to work.

When I try to call s3upload, I am getting the error that it is not available. To debug this problem, I ran:

println  file.inputStream.metaClass.methods*.name.sort().unique()

Which outputs (no s3upload):

[available, close, equals, getChannel, getClass, getFD, hashCode, mark, markSupported, notify, notifyAll, read, reset, skip, toString, wait]

Here is the source I have been using:

<g:uploadForm action="uploadFromInputStream">
    <input type="file" name="photo">
    <input type="submit" value="upload">
</g:uploadForm>


def file = request.getFile('photo')
def uploadedFile = file.inputStream.s3upload(file.originalFilename) {
    bucket "file-upload-from-inputstream"
}

I've been following the documentation here: http://blanq.github.com/grails-aws/, which by the way, points to a 404 for the source code for this project: https://github.com/blanq/grails-aws.

bgrins avatar Feb 11 '13 04:02 bgrins

And the version of the plugin I'm using:

    runtime ":aws:1.2.12.2"

bgrins avatar Feb 11 '13 04:02 bgrins

I was unable to reproduce this issue using the latest version of the plugin (1.6.7.1) and Grails 2.2.4

There is now a grails-aws-example project and a branch for this specific issue: https://github.com/j4y/grails-aws-example/tree/grails-aws-issue-21-test

        def file = request.getFile('file')
        def uploadedFile = file.inputStream.s3upload(file.originalFilename) {
        }
        fileInstance.fileName = file.getOriginalFilename()
        fileInstance.objectKey = fileInstance.fileName

This issue was created 10 months ago so I doubt you are still waiting. Let me know if there is anything I can do to help.

j4y avatar Dec 17 '13 02:12 j4y

FYI, in the working example. the debug code still does not include s3upload as a method name.

println  file.inputStream.metaClass.methods*.name.sort().unique()

outputs:

[available, close, equals, getChannel, getClass, getFD, hashCode, mark, markSupported, notify, notifyAll, read, reset, skip, toString, wait]

j4y avatar Dec 17 '13 03:12 j4y

Hi!

I am experiencing the same problem with version 1.9.13.3 and Grails 2.5.0. The s3upload method is successfully injected in the File class, but not InputStream.

Any clues?

I can open a separate issue if prefered.

Best, Gregor

link-point avatar Sep 10 '15 11:09 link-point

I added a branch with grails 2.5.1, but it is failing: https://travis-ci.org/grails-aws/grails-aws/builds/80093175

 Error Fatal error running tests: org/hamcrest/SelfDescribing (NOTE: Stack trace has been filtered. Use --verbose to see entire trace.)
java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing
    at _GrailsTest$_run_closure1.doCall(_GrailsTest.groovy:102)
    at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:133)
    at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16_closure18.doCall(GantBinding.groovy:185)
    at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16_closure18.doCall(GantBinding.groovy)
    at org.codehaus.gant.GantBinding.withTargetEvent(GantBinding.groovy:90)
    at org.codehaus.gant.GantBinding.this$4$withTargetEvent(GantBinding.groovy)
    at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16.doCall(GantBinding.groovy:185)
    at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16.doCall(GantBinding.groovy)
    at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:133)
    at TestApp$_run_closure1.doCall(TestApp.groovy:32)
    at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:133)
    at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16_closure18.doCall(GantBinding.groovy:185)
    at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16_closure18.doCall(GantBinding.groovy)
    at org.codehaus.gant.GantBinding.withTargetEvent(GantBinding.groovy:90)
    at org.codehaus.gant.GantBinding.this$4$withTargetEvent(GantBinding.groovy)
    at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16.doCall(GantBinding.groovy:185)
    at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16.doCall(GantBinding.groovy)
    at gant.Gant$_dispatch_closure5.doCall(Gant.groovy:381)
    at gant.Gant$_dispatch_closure7.doCall(Gant.groovy:415)
    at gant.Gant$_dispatch_closure7.doCall(Gant.groovy)
    at gant.Gant.withBuildListeners(Gant.groovy:427)
    at gant.Gant.this$2$withBuildListeners(Gant.groovy)
    at gant.Gant.dispatch(Gant.groovy:415)
    at gant.Gant.this$2$dispatch(Gant.groovy)
    at gant.Gant.invokeMethod(Gant.groovy)
    at gant.Gant.executeTargets(Gant.groovy:591)
    at gant.Gant.executeTargets(Gant.groovy:590)
Caused by: java.lang.ClassNotFoundException: org.hamcrest.SelfDescribing
    ... 27 more
| Error Fatal error running tests: org/hamcrest/SelfDescribing

j4y avatar Sep 13 '15 13:09 j4y

I have fixed the grails 2.5.1 build problems and added an integration test for this:

    // from S3IntegrationTests.groovy
    @Test
    void inputStreamS3UploadThrowsS3ServiceException() {

        def mockInputStream = new ByteArrayInputStream('mockInputStream'.getBytes())
        def mockFilename = 'destinationS3Key.txt'

        def message = shouldFail(S3ServiceException) {

            def uploadedFile = mockInputStream.s3upload(mockFilename) {
                bucket "missing-bucket"
            }
        }
        assert message == "S3 Error Message."
    }

Is this the same way that you are using the s3upload closure? Please post a full stack trace if you can.

j4y avatar Sep 15 '15 02:09 j4y

Yes, this is the simillar way we are using the s3upload closure. I have tried in on two different input streams:

First, I called the closure on multipartFile.inputStream (http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/multipart/MultipartFile.html).

Second, I created ByteArrayInputStream and called the closure on that one.

In both cases I get the error that the closure cannot be found on the stream object. Unfortunately, I don't have the stack trace right now. Basically, if I execute the line that @bgrins did (println file.inputStream.metaClass.methods*.name.sort().unique()), I don't get s3upload printed out.

link-point avatar Sep 15 '15 10:09 link-point