I have a webapp running on Tomcat 6, one class checks for existence of directory and creates it if doesn't exist -
// make sure path exists
File f = new File(value);
if (!f.exists()) {
if (!f.mkdirs()) {
throw new RuntimeException("Failed creating directory " + value);
}
}
Now, it all works just fine when running on my local machine, but when executed on EC2 instance, I see the following at catalina.out -
2012-05-30 06:57:28 main ConfigService [INFO] Directory path not exists, creating /usr/share/tomcat6/webapps/ROOT/WEB-INF/data/temp/currency
2012-05-30 06:57:28 main DefaultListableBeanFactory [INFO] Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1b4c1d7: defining beans [fetchAppRankingJob,fetchCurrencyRatesJob,fetchReviewsJob,sendDailyReportJob,importSalesReportJob,fetchSalesReportJob,processSalesReportsJob,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0,org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0,org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0,org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,org.springframework.scheduling.support.ScheduledMethodRunnable#0,org.springframework.scheduling.support.ScheduledMethodRunnable#1,org.springframework.scheduling.support.ScheduledMethodRunnable#2,org.springframework.scheduling.support.ScheduledMethodRunnable#3,org.springframework.scheduling.support.ScheduledMethodRunnable#4,org.springframework.scheduling.config.ScheduledTaskRegistrar#0,appsales-scheduler,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy
2012-05-30 06:57:28 main ContextLoader [ERROR] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fetchCurrencyRatesJob' defined in file [/var/lib/tomcat6/webapps/ROOT/WEB-INF/classes/com/appround/collect/currency/FetchCurrencyRatesJob.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.appround.collect.currency.FetchCurrencyRatesJob]: Constructor threw exception; nested exception is java.lang.RuntimeException: Failed creating directory /usr/share/tomcat6/webapps/ROOT/WEB-INF/data/temp/currency
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:997)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:943)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:385)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:284)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4206)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4705)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:799)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:779)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:601)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1079)
at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:1002)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:506)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1317)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:324)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1065)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
at org.apache.catalina.core.StandardService.start(StandardService.java:525)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.appround.collect.currency.FetchCurrencyRatesJob]: Constructor threw exception; nested exception is java.lang.RuntimeException: Failed creating directory /usr/share/tomcat6/webapps/ROOT/WEB-INF/data/temp/currency
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:162)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:76)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:990)
... 37 more
Caused by: java.lang.RuntimeException: Failed creating directory /usr/share/tomcat6/webapps/ROOT/WEB-INF/data/temp/currency
at com.appround.collect.ConfigService.getPathProperty(ConfigService.java:109)
at com.appround.collect.currency.FetchCurrencyRatesJob.<init>(FetchCurrencyRatesJob.java:18)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
... 39 more
I prefer writing to /home/ec2-user/collect/data, tried writing to my webapp's directory because it should have writing privilege to WEB-INF folder.
I've tried granting file permission write/read to that folder at /usr/share/tomcat6/conf/catalina.policy -
grant {
permission java.io.FilePermission "/home/ec2-user/collect/data", "read, write";
permission java.io.FilePermission "/home/ec2-user/collect/data/*", "read, write";
}
Still, no luck.
Any clue?
Thanks!
I am assuming you are using Amazon Linux since you mention the ec2-user
.
What permissions are set on the parent folder /usr/share/tomcat6/webapps/
where you try to create the new one? Usually the user running Tomcat (should also be called tomcat
) does not have write permission there unless you set it explicitly using chmod u+w
.
In adddition the tomcat
user is not allowed to write to a different user's home (/home/ec2-user/
in your case), unless you give the user permissions for this directory. Your example is a little confusing there since you mention trying to write to the webapps
folder but specify the ec2-user
's home directory in the policy file.
Generally, if you want to create temporary data files, I would suggest using File.createTempFile(..)
to create them, they will automatically be placed in the standard temporary folder. If you would like to create a dedicated folder for data files yourself, /var/tmp/
may be better suited since it is the standard unix location for temporary files (/tmp/
may be cleared upon reboot, so please do not put any persistent files there).