Closed
Description
Since version 1.4.5 we notice our application produces jar_cache*.tmp files. In previous versions it did not. In our case the jar_cache*.tmp files risk filling the disk after a while.
We found the cause:
- Locations for static content are auto configured by Spring Boot.
Default locations for static resources in the resolveChain (in order) are:- (ServletContext) /
- classpath:/META-INF/resources/
- classpath:/resources/
- classpath:/static/
- classpath:/public/
- In version 1.4.4 getting a resource from ServletContext root returned instances of EmptyResource and getUrl() returned null. So the ServletContext location got skipped and then resources were retrieved from classpath:/META-INF/resources/. This changed in version 1.4.5: Resource handling is inconsistent across different embedded containers #8299. ServletContext now returns a valid URL to the resource.
- Our static resources are contained in a jar in our application jar. So jar-in-jar. (URL to the resource looks like this: jar:war:file:application.jar*/BOOT_INF/lib/resources.jar!/META-INF/resources/favicon.ico) Retrieving the static resource requires JVM to use jar_cache*.tmp files. (using File.deleteOnExit). This seems to occur when you do resource.contentLength().
On Debian/OpenJDK we can only see these jar_cache*.tmp files using lsof; they are open but deleted files. These do not get released until the application exits. So they still take up space and fill the disk. Similarly on Windows/SunJDK we can see the jar_cache*.tmp files accumulate and they are only deleted when the application exits. This seems to be a known/old phenomenon with the JVM.
In short:
Due to changes in the behaviour of ServletContext static resources our application now performs jar-in-jar lookups and accumulates tmp files.
Our solution:
We used the spring.resources.static-locations application property to customize the order of the locations and put classpath:/META-INF/resources/ first.