Nordenheim Nordenheim - 1 month ago 9
reST (reStructuredText) Question

Dropwizard FileNotFoundException whilst the file is present and seen by debugger

I am testing my endpoint built with dropwizard, but something goes wrong:

@Test
public void testPostWithFileSuccess() throws Exception
{
FileDataBodyPart filePart = new FileDataBodyPart("file", new File(fixture("resources/testImage.jpg")));
filePart.setContentDisposition(FormDataContentDisposition.name("file").fileName("testImage.jpg").build());

FormDataMultiPart request = new FormDataMultiPart();
request.field("data", fixture("resources/postWithFileSuccess.json"), MediaType.APPLICATION_JSON_TYPE);
request.bodyPart(filePart);

WebTarget target = mClient.target("http://localhost:8080/crackers").register(MultiPartFeature.class);
Response response = target
.request()
.post(Entity.entity(request, MediaType.MULTIPART_FORM_DATA));

assertThat(response.getStatus()).isEqualTo(200);
}


What actually happens is the test fails on
.post(Entity.entity(request, MediaType.MULTIPART_FORM_DATA));
with the following expection:


javax.ws.rs.ProcessingException: java.io.FileNotFoundException: Invalid file path
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:287)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:252)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:684)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:681)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:681)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:437)
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:343)
at org.example.project.resources.CrackersTest.testPostWithFileSuccess(CrackersTest.java:201)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.io.FileNotFoundException: Invalid file path
at java.io.FileInputStream.(FileInputStream.java:133)
at org.glassfish.jersey.message.internal.FileProvider.writeTo(FileProvider.java:115)
at org.glassfish.jersey.message.internal.FileProvider.writeTo(FileProvider.java:67)
at org.glassfish.jersey.media.multipart.internal.MultiPartWriter.writeTo(MultiPartWriter.java:232)
at org.glassfish.jersey.media.multipart.internal.MultiPartWriter.writeTo(MultiPartWriter.java:79)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1130)
at org.glassfish.jersey.client.ClientRequest.doWriteEntity(ClientRequest.java:517)
at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:499)
at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:388)
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:285)
... 42 more


I'm not completely sure, as if the file was not present or the path would have been wrong, an
Exception
would have been thrown on
new File(...)
declaration.

There is obviously something wrong with
filePart
, but what? If I comment
request.bodyPart(filePart);
out, the test just fails with a comparison error (that's expected).

Answer

The issue is that fixture(...) method returns Resources.toString(Resources.getResource(filename), charset).trim(), hence debugger sees the file, but post(...) can't process it.

To fix the issue, instead of

new File(fixture("resources/testImage.jpg"))

I should have used

new File(Resources.getResource("resources/testImage.jpg").toURI())

Complete fixed method listing:

@Test
public void testPostWithFileSuccess() throws Exception
{
    FileDataBodyPart filePart = new FileDataBodyPart("file", new File(Resources.getResource("resources/testImage.jpg").toURI()));
    filePart.setContentDisposition(FormDataContentDisposition.name("file").fileName("testImage.jpg").build());

    FormDataMultiPart request = new FormDataMultiPart();
    request.field("data", fixture("resources/postWithFileSuccess.json"), MediaType.APPLICATION_JSON_TYPE);
    request.bodyPart(filePart);

    WebTarget target = mClient.target("http://localhost:8080/crackers").register(MultiPartFeature.class);
    Response response = target
            .request()
            .post(Entity.entity(request, MediaType.MULTIPART_FORM_DATA));

    assertThat(response.getStatus()).isEqualTo(200);
}
Comments