I'm trying to upload file and then read it, everything is working fine, but not when I put @Async
annotation on the handler method.
I don't want the user to keep waiting until it processes the file. But after putting this annotation I get java.lang.IllegalStateException: File has been moved - cannot be read again
exception. What happens and how do I fix this? As I understand, Spring could be just clearing the file because request-response ends and it cleans it up. But shouldn't @Async
prevent this?
Sample Spring Boot application:
@SpringBootApplication
@EnableSwagger2
@ComponentScan(value = "hello")
@EnableAsync
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.regex("/api/.*"))
.build();
}
}
Upload controller:
@RestController
@RequestMapping(value = "/files")
public class FilesController {
@Inject
private Upload upload;
@RequestMapping(method = RequestMethod.POST)
public void addSource(@RequestParam MultipartFile file) throws IOException, InterruptedException {
upload.process(file);
}
}
Upload service:
@Component
public class Upload {
@Async
public void process(MultipartFile file) throws InterruptedException, IOException {
sleep(2000);
System.out.println(new String(IOUtils.readFully(file.getInputStream(), -1, false)));
}
}
And now I get java.io.FileNotFoundException
. I'm not sure what I'm missing here. Probably I'm doing something wrong as I couldn't find any error on this and I'd think this is very common use-case.