Tuesday 26 October 2010

Java /temp directory - set in catalina.properties

Error keywords seen:
javax.imageio.IIOException: Can't create cache file!
java.io.IOException: No such file or directory
Operating System: Solaris 10
Software: Tomcat (/tcServer)

Customers complained that they could not use an image upload feature of the site. The application logs were filled with the following error:

javax.imageio.IIOException: Can't create cache file!
at javax.imageio.ImageIO.createImageInputStream(ImageIO.java:335)
at javax.imageio.ImageIO.read(ImageIO.java:1325)
at uk.co.site.utils.ImageUtility.resizeImage(ImageUtility.java:24)
at uk.co.site.utils.ImageUtility.resizeImage(ImageUtility.java:19)
...
at org.springframework.web.servlet.mvc.SimpleFormController.processFormSubmission(SimpleFormController.java:267)
...
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
...
Caused by: java.io.IOException: No such file or directory
at java.io.UnixFileSystem.createFileExclusively(Native Method)
at java.io.File.checkAndCreate(File.java:1704)
at java.io.File.createTempFile(File.java:1792)
at javax.imageio.stream.FileCacheImageInputStream.(FileCacheImageInputStream.java:84)
at com.sun.imageio.spi.InputStreamImageInputStreamSpi.createInputStreamInstance(InputStreamImageInputStreamSpi.java:51)
at javax.imageio.ImageIO.createImageInputStream(ImageIO.java:331)
...

 

This is telling us that tomcat can't write to its temporary directory. Tomcat writes to this directory when it needs to write out transient temporary files - here, while resizing an image.

The temporary directory is by [catalina_base]/temp by default - which is not always created on install. Therefore, 99 times out of 100, the thing to do is create [catalina_base]/temp, and check that the tomcat user has permissions to write to it.

When I first saw this problem, it was the 1 time out of 100 where something else was going on. The location of the temporary directory can be overridden - normally by specifying a JVM argument in setenv.sh:

-Djava.io.tmpdir=[some_location]
(Onto APPLICATION_OPTS)

When I checked setenv.sh (and the arguments of the running process too) - java.io.tmpdir was set as expected. So what was going on? The answer lay in catalina.properties - it is also possible to override the directory structure here, and this takes precedence over the JVM arguments (something I found surprising). It is set by:

tomcat/conf/catalina.properties:
java.io.tmpdir=[some_location]

Editing this and restarting is the only way to redirect the temporary files in this case.

1 comment:

Danny said...

Having heard the nursery rhyme too many times this evening I would like to have an EIEIOException.

That is all