In a Spring MVC-based project, Spring's CommonsMultipartFile is used to handle the file upload/transfer process. The overall file uploading process is working fine in Linux if I run the project from STS, but when I export the WAR file from the source, deploy the WAR and run the process it shows, a Permission Denied issue. Here is the sample code that was written to handle the file upload process:
Controller file Code:
@RequestMapping(value = "/jsonBulkUploadRequest", method = RequestMethod.POST)
@ResponseBody
public void uploadBulkFile(BulkUploadEntity remittance) throws Exception {
bulkUploader.uploadBulkFile(remittance);
}
Service File Code
public void uploadBulkFile(BulkUploadEntity uploadItem) throws Exception {
CommonsMultipartFile file = uploadItem.getFile();
fileUploadStatus.put(file.getOriginalFilename().toUpperCase(), "Inprogress");
//added time as file with same name can be uploaded
String fileNameWithDateTime = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf(STR_DOT)) + STR_DASH
+ nOFACDateUtils.getCurrentTimeStamp() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(STR_DOT));
File f = new File(fileNameWithDateTime);
file.transferTo(f); // While inside this method, permission denied error raised
// process other uploaded file related task
f.delete();
}
CommonsMultipartFile file of Spring MultipartFile:
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
if (!isAvailable()) {
throw new IllegalStateException("File has already been moved - cannot be transferred again");
}
if (dest.exists() && !dest.delete()) {
throw new IOException("Destination file [" + dest.getAbsolutePath() + "] already exists and could not be deleted");
}
try {
this.fileItem.write(dest);
if (logger.isDebugEnabled()) {
String action = "transferred";
if (!this.fileItem.isInMemory()) {
action = isAvailable() ? "copied" : "moved";
}
logger.debug("Multipart file '" + getName() + "' with original filename [" +
getOriginalFilename() + "], stored " + getStorageDescription() + ": " +
action + " to [" + dest.getAbsolutePath() + "]");
}
}
catch (FileUploadException ex) {
throw new IllegalStateException(ex.getMessage());
}
catch (IOException ex) {
throw ex;
}
catch (Exception ex) {
logger.error("Could not transfer to file", ex);
throw new IOException("Could not transfer to file: " + ex.getMessage());
}
}
Interestingly there are no logs in catalina.out file, but here is the exception I receive in the browser network tab:
java.io.FileNotFoundException: 08_06_2022-20220906112643.xlsx (Permission denied)
java.io.FileOutputStream.open0(Native Method)
java.io.FileOutputStream.open(FileOutputStream.java:270)
java.io.FileOutputStream.<init>(FileOutputStream.java:213)
java.io.FileOutputStream.<init>(FileOutputStream.java:162)
org.apache.commons.fileupload.disk.DiskFileItem.write(DiskFileItem.java:394)
org.springframework.web.multipart.commons.CommonsMultipartFile.transferTo(CommonsMultipartFile.java:142)
com.nazdaqTechnologies.nofac.service.BulkUploader.uploadBulkFile(BulkUploader.java:68)
com.nazdaqTechnologies.nofac.controller.SdnListController.uploadBulkFile(SdnListController.java:777)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.apache.catalina.filters.CorsFilter.handleNonCORS(CorsFilter.java:368)
org.apache.catalina.filters.CorsFilter.doFilter(CorsFilter.java:174)
The above log clearly indicates that the file we are looking for is not found either for permission issue or the file is not there, but my question is why this issue is not raised when I run and debug the source code in Linux?
To raise the issue, I use the same Linux server, the same Tomcat where the WAR files are deployed through RDP, but when I run the source or debug, the file upload process works smoothly. The issue is raised only when I export the source code as WAR and deploy the WAR file in the tomcat and test the file upload. It seems weird to me, and have no idea what is the exact reason and what is the solution.
Hope someone here in StackOverflow can help me to identify and if possible solve the issue.
- Thanks