title: AWS EC2 tomcat permission denied creating/writing to file
body: <p>I have a tomcat running on an elastic beanstalk EC2:</p>
  
  <blockquote>
    <p>64bit Amazon Linux 2015.09 v2.0.4 running Tomcat 8 Java 8</p>
  </blockquote>
  
  <p>I'm having trouble when the web app wants to create a new directory/file. I'm getting the following error in catalina.out</p>
  
  <pre><code>java.io.IOException: java.io.FileNotFoundException: /home/ec2-user/images/companydata/images/2/10/ac3feab8-a2db-4052-9614-eea41c0a509e.png (Permission denied)
          at org.apache.catalina.core.ApplicationPart.write(ApplicationPart.java:121)
          at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.transferTo(StandardMultipartHttpServletRequest.java:260)
          at controler.RestControllerCompanyMobilePOST.uploadImage(RestControllerCompanyMobilePOST.java:183)
          at controler.RestControllerCompanyMobilePOST$$FastClassBySpringCGLIB$$538488ab.invoke(&lt;generated&gt;)
          at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
          at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
          at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:68)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
          at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
          at controler.RestControllerCompanyMobilePOST$$EnhancerBySpringCGLIB$$1e56492.uploadImage(&lt;generated&gt;)
          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:497)
          at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
          at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
          at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
          at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
          at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
          at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
          at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
          at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
          at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
          at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)
          at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
          at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
          at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316)
          at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
          at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
          at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
          at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
          at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
          at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:168)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
          at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
          at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:213)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
          at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
          at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
          at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
          at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
          at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
          at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
          at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:116)
          at org.springframework.boot.context.web.ErrorPageFilter.access$000(ErrorPageFilter.java:60)
          at org.springframework.boot.context.web.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:91)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
          at org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:109)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
          at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
          at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
          at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
          at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
          at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:676)
          at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617)
          at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
          at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
          at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
          at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
          at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
          at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
          at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
          at java.lang.Thread.run(Thread.java:745)
  Caused by: java.io.FileNotFoundException: /home/ec2-user/images/companydata/images/2/10/ac3feab8-a2db-4052-9614-eea41c0a509e.png (Permission denied)
          at java.io.FileOutputStream.open0(Native Method)
          at java.io.FileOutputStream.open(FileOutputStream.java:270)
          at java.io.FileOutputStream.&lt;init&gt;(FileOutputStream.java:213)
          at java.io.FileOutputStream.&lt;init&gt;(FileOutputStream.java:162)
          at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.write(DiskFileItem.java:395)
          at org.apache.catalina.core.ApplicationPart.write(ApplicationPart.java:119)
          ... 97 more
  </code></pre>
  
  <p>So,, I know it's a permissions issue so I googled and I've found how to find out what user started tomcat by typing:</p>
  
  <pre><code>[root@ip-172-31-1-99 tomcat8]# ps auxwww | grep -v grep | grep tomcat
  ec2-user 25653  0.0  0.1 107940   676 pts/0    T    18:29   0:00 tail -F catalina.2016-01-03.log catalina.2016-01-04.log catalina.2016-01-05.log host-manager.2016-01-03.log host-manager.2016-01-05.log localhost.2016-01-03.log localhost.2016-01-05.log manager.2016-01-03.log manager.2016-01-05.log tomcat8-initd.log
  ec2-user 25665  0.0  0.1 107940   752 pts/0    T    18:30   0:00 tail -F catalina.2016-01-03.log catalina.2016-01-04.log catalina.2016-01-05.log host-manager.2016-01-03.log host-manager.2016-01-05.log localhost.2016-01-03.log localhost.2016-01-05.log manager.2016-01-03.log manager.2016-01-05.log tomcat8-initd.log
  ec2-user 25811  0.0  0.1 107940   656 pts/0    T    18:45   0:00 tail -F catalina.2016-01-03.log catalina.2016-01-04.log catalina.2016-01-05.log host-manager.2016-01-03.log host-manager.2016-01-05.log localhost.2016-01-03.log localhost.2016-01-05.log manager.2016-01-03.log manager.2016-01-05.log tomcat8-initd.log
  tomcat   26525  4.7 72.0 2400404 436580 ?      Sl   19:22   4:49 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Xms256m -Xmx256m -XX:MaxPermSize=64m -classpath :/usr/share/tomcat8/bin/bootstrap.jar:/usr/share/tomcat8/bin/tomcat-juli.jar:/usr/share/java/commons-daemon.jar -Dcatalina.base=/usr/share/tomcat8 -Dcatalina.home=/usr/share/tomcat8 -Djava.awt.headless=true -Djava.endorsed.dirs= -Djava.io.tmpdir=/var/cache/tomcat8/temp -Djava.util.logging.config.file=/usr/share/tomcat8/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager org.apache.catalina.startup.Bootstrap start
  </code></pre>
  
  <p>And I can see tomcat was started by the user tomcat.</p>
  
  <p>So, I changed the root folder where I want to store all the details and gave chown to user tomcat and group tomcat, and also chmod 777 on it</p>
  
  <blockquote>
    <p>/home/ec2-user/images/</p>
    
    <p>drwxrwxrwx 2 tomcat tomcat 4096 Jan  5 19:40 images</p>
  </blockquote>
  
  <p>But I'm getting the same permission denied error.</p>
  
  <p>Here is the method:</p>
  
  <pre><code>String StoreImageHere = 
                      locationOfCompanyData 
                      + File.separator
                      + locationOfImage 
                      + File.separator
                      + user.getCompany_id() 
                      + File.separator +
                      + notUpdatedImage.getServer_questionnaire_attempt_key()
                      + File.separator  ; 
  
              File uploadedFileFolderLocation = new File(locationRoot, StoreImageHere);           
              uploadedFileFolderLocation.mkdirs();
  
              String storeImageName = StoreImageHere + notUpdatedImage.getImage_name();   
              File uploadedFile = new File(locationRoot, storeImageName);                     
  
              try {
                  file.transferTo(uploadedFile);
              } catch (IllegalStateException e) {
                  e.printStackTrace();
                  logger.error(user.getUsers_email()
                          + "  /api/mobile/uploadImage/{server_image_id}/ " 
                          + " userID[" + user.getUsers_id() + "]"
                          + " error[" + e.getMessage() + "]");
              } catch (IOException e) {
                  e.printStackTrace();
                  logger.error(user.getUsers_email()
                          + "  /api/mobile/uploadImage/{server_image_id}/ " 
                          + " userID[" + user.getUsers_id() + "]"
                          + " error[" + e.getMessage() + "]");
              }
  
              if(uploadedFile.exists()) {
                  notUpdatedImage.setSync(ENUM_SYNC_STATUS.SYNCED.getValue());
                  notUpdatedImage = mobileManagment.updateImage(user, notUpdatedImage, ENUM_ACTIVITY_TYPE.ANSWER_INPUT_UPLOADED);         
                   return new Gson().toJson(notUpdatedImage); 
              } else {
                  logger.error(user.getUsers_email()
                          + "  /api/mobile/"+VERSION+"/uploadImage/{server_image_id}/ " 
                          + " userID[" + user.getUsers_id() + "]"
                          + " dest.exists() == false ");
              }
  </code></pre>
  
  <p>I ran </p>
  
  <blockquote>
    <p>setenforce 0</p>
  </blockquote>
  
  <p>and it returned</p>
  
  <blockquote>
    <p>setenforce: SELinux is disabled</p>
  </blockquote>
  
  <p>On a windows machine, it takes this parameter</p>
  
  <blockquote>
    <p>location.sever.root=C:/Users/killesk_beast/Desktop/temp/</p>
  </blockquote>
  
  <p>and on the linux machine, it takes this</p>
  
  <blockquote>
    <p>location.sever.root=/home/ec2-user/images/</p>
  </blockquote>
  
  <p>Unless there is a simple mistake that I'm just not seeing</p>