Here is a quick post about a ticky issue that i recently spent some time on and felt good to resolve it. Its about proper packaging and usage of ehache in a spring data based layered application.
The data-layer of the application is used by two client applications (both running on same linux box) by following means.
1. By a web app running on weblogic using weblogic user.
2. By a batch process running on another jvm as standalone application.
Things worked fine when ‘weblogic’ user is used to run both wls server and the batch process. But when the batch process is executed with another user (say ‘batchuser’ while wls running with ‘weblogic’ user we got the following exception.
2014-03-26 14:38:01,695 ERROR [main] [org.springframework.batch.core.launch.support.CommandLineJobRunner] – Job Terminated in error: Error creating bean with name ‘entityManagerFactory’ defined in class path resource [applicationContext-dl.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build EntityManagerFactory
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘entityManagerFactory’ defined in class path resource [applicationContext-dl.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build EntityManagerFactory at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1488)
We are using ehcache and it is configured to use ‘java.io.tmpdir’ (which defaults to /tmp in linux) for the diskstore storage option. Also all the individual cache definitions in ehcache are configured to overflow-to-disk. Since both the applications use the same ehcache.xml file (packaged in the datalayer.jar file) both the applications try to reserve space in /tmp for overflow using same chache names for the entities. When both use same login id they are able to share the files representing the caches but when using different login ids the unix file system does not allow one user to use a file that is created and exclusively locked by different user.
Solutions for us was easy. We do not need the diskstore facility for now as we only have 4 objects to cache and they are small enough to not bother our memory footprint much. So we removed the diskstore definition from cache and it has worked fine. But the correct solution is to not use the same space for storing caches from two different user processes. One could use ‘user.home’ or something similar for diskstore path. Another way could be to not package the ehcache.xml configuration file in datalayer.jar and let the client supply its own configured file in classpath.