現象
org.apache.poi.openxml4j.exceptions.InvalidOperationException: Can't open the specified file: '/tmp/poifiles/...'
- 環境依存。発生する環境と発生しない環境がある。
原因
- /tmp の容量不足。
- /tmp を df で監視しながらバッチ処理を実行すると、/tmp が 100% になりバッチが異常終了した。
蛇足
- http://download.java.net/jdk6/source/ から jdk-6u21-ea-src-b05-jrl-29_may_2010.jar をダウンロードする。
% cd ~/Documents/src
% curl -O http://download.java.net/jdk6/6u21/promoted/b05/jdk-6u21-ea-src-b05-jrl-29_may_2010.jar
% java -jar jdk-6u21-ea-src-b05-jrl-29_may_2010.jar
- [ACCEPT] を押す。
- Select install directory: src
- jvm のソースをのぞいてみる。
% cd ~/Documents/src/jdk-6u21-ea-src-b05-jrl-29_may_2010/src % grep -R java.io.tmpdir * deploy/src/common/share/classes/com/sun/deploy/util/NativeLibraryBundle.java: java.io.tmpdir deploy/src/common/share/classes/com/sun/deploy/util/NativeLibraryBundle.java: String rootDirName = System.getProperty("java.io.tmpdir") + j2se/src/linux/doc/man/ja/rmid.1:\f2System.err\fP ???Ф?????Ϥϡ??ե?????˥?????쥯?Ȥ???롣???Υե?????? \f2java.io.tmpdir\fP ?????ƥ?ץ??ѥƥ????ǻ??ꤵ???ǥ??쥯?ȥ? (?̾?? \f2/var/tmp\fP ?ޤ??? \f2/tmp\fP) ?ˤ??롣 ?ե?????̾????Ƭ???? \f2rmid\-err\fP ?ǡ????????? \f2"tmp"\fP ?Ǥ??? j2se/src/linux/doc/man/rmid.1:Output printed to \f2System.err\fP is redirected to a file. This file is located in the directory specified by the \f2java.io.tmpdir\fP system property (typically \f2/var/tmp\fP or \f2/tmp\fP) with the prefix \f2"rmid\-err"\fP and the suffix \f2"tmp"\fP. j2se/src/share/classes/com/sun/tools/javac/util/DefaultFileManager.java: preindexCacheLocation = options.get("java.io.tmpdir"); j2se/src/share/classes/com/sun/tools/javac/zip/ZipFileIndex.java: * the value of the "java.io.tmpdir" system property. j2se/src/share/classes/java/io/File.java: new GetPropertyAction("java.io.tmpdir"))); j2se/src/share/classes/java/io/File.java: * <code>java.io.tmpdir</code>. On UNIX systems the default value of this j2se/src/share/classes/java/lang/System.java: * <tr><td><code>java.io.tmpdir</code></td> j2se/src/share/classes/java/util/logging/FileHandler.java: String tmpDir = System.getProperty("java.io.tmpdir"); j2se/src/share/classes/javax/imageio/ImageIO.java: * java.io.tmpdir system property. j2se/src/share/classes/javax/imageio/ImageIO.java: GetPropertyAction a = new GetPropertyAction("java.io.tmpdir"); j2se/src/share/classes/javax/management/loading/MLet.java: // can't read the MLET_LIB_DIR or java.io.tmpdir properties j2se/src/share/classes/javax/management/loading/MLet.java: String tmpDir = System.getProperty("java.io.tmpdir"); j2se/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/package.html:the JVM implementation. However, the <tt>java.io.tmpdir</em> system j2se/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java: * This method generally returns the value of the java.io.tmpdir j2se/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java: * the directory indicated in the java.io.tmpdir property. However, j2se/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java: * Solaris java.io.tmpdir property were set to /tmp by default j2se/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java: * Why is java.io.tmpdir on Solaris set to "/var/tmp/" when the j2se/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java: String tmpdir = System.getProperty("java.io.tmpdir"); j2se/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java: * java.io.tmpdir is set to "/var/tmp/" on Solaris and Linux, j2se/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java: * to java.io.tmpdir. j2se/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java: * changed such that the java.io.tmpdir string no longer terminates j2se/src/share/classes/sun/security/provider/SeedGenerator.java: File f = new File(p.getProperty("java.io.tmpdir")); j2se/src/share/demo/java2d/J2DBench/src/j2dbench/ResultSet.java: "java.io.tmpdir", j2se/src/share/native/java/lang/System.c: PUTPROP_ForPlatformCString(props, "java.io.tmpdir", sprops->tmp_dir); j2se/src/share/sample/jmx/jmx-scandir/test/com/sun/jmx/examples/scandir/config/XmlConfigUtilsTest.java: final String tmp = System.getProperty("java.io.tmpdir"); j2se/src/share/sample/jmx/jmx-scandir/test/com/sun/jmx/examples/scandir/config/XmlConfigUtilsTest.java: final String tmp = System.getProperty("java.io.tmpdir"); j2se/src/share/sample/jmx/jmx-scandir/test/com/sun/jmx/examples/scandir/DirectoryScannerTest.java: final String tmpdir = System.getProperty("java.io.tmpdir"); j2se/src/share/sample/jmx/jmx-scandir/test/com/sun/jmx/examples/scandir/DirectoryScannerTest.java: final String tmpdir = System.getProperty("java.io.tmpdir"); j2se/src/share/sample/jmx/jmx-scandir/test/com/sun/jmx/examples/scandir/DirectoryScannerTest.java: bean.setRootDirectory(System.getProperty("java.io.tmpdir")); j2se/src/share/sample/jmx/jmx-scandir/test/com/sun/jmx/examples/scandir/DirectoryScannerTest.java: final String tmpdir = System.getProperty("java.io.tmpdir"); j2se/src/solaris/doc/sun/man/man1/ja/rmid.1:\f2System.err\fP ???Ф?????Ϥϡ??ե?????˥?????쥯?Ȥ???롣???Υե?????? \f2java.io.tmpdir\fP ?????ƥ?ץ??ѥƥ????ǻ??ꤵ???ǥ??쥯?ȥ? (?̾?? \f2/var/tmp\fP ?ޤ??? \f2/tmp\fP) ?ˤ??롣 ?ե?????̾????Ƭ???? \f2rmid\-err\fP ?ǡ????????? \f2"tmp"\fP ?Ǥ??? j2se/src/solaris/doc/sun/man/man1/rmid.1:Output printed to \f2System.err\fP is redirected to a file. This file is located in the directory specified by the \f2java.io.tmpdir\fP system property (typically \f2/var/tmp\fP or \f2/tmp\fP) with the prefix \f2"rmid\-err"\fP and the suffix \f2"tmp"\fP.
215 /** 216 * Return the name of the temporary directory being searched for 217 * HotSpot PerfData backing store files. 218 * <p> 219 * This method generally returns the value of the java.io.tmpdir 220 * property. However, on some platforms it may return a different 221 * directory, as the JVM implementation may store the PerfData backing 222 * store files in a different directory for performance reasons. 223 * 224 * @return String - the name of the temporary directory. 225 */ 226 public static String getTempDirectory() { 227 return tmpDirName; 228 } 229 /** 230 * Return the name of the temporary directory to be searched 231 * for HotSpot PerfData backing store files for a given user. 232 * <p> 233 * This method generally returns the name of a subdirectory of 234 * the directory indicated in the java.io.tmpdir property. However, 235 * on some platforms it may return a different directory, as the 236 * JVM implementation may store the PerfData backing store files 237 * in a different directory for performance reasons. 238 * 239 * @return String - the name of the temporary directory. 240 */ 241 public static String getTempDirectory(String user) { 242 return tmpDirName + dirNamePrefix + user + File.separator; 243 } 244 /* 245 * this static initializer would not be necessary if the 246 * Solaris java.io.tmpdir property were set to /tmp by default 247 */ 248 static { 249 /* 250 * Why is java.io.tmpdir on Solaris set to "/var/tmp/" when the 251 * HotSpot JVM os:get_temp_path() method returns "/tmp/" 252 * 253 * Why do Solaris and Windows return a string with a trailing 254 * file separator character where as Linix does not? (this change 255 * seems to have occurred sometime during hopper beta) 256 */ 257 String tmpdir = System.getProperty("java.io.tmpdir"); 258 if (tmpdir.compareTo("/var/tmp/") == 0) { 259 /* 260 * shared memory files are created in /tmp. Interestingly, 261 * java.io.tmpdir is set to "/var/tmp/" on Solaris and Linux, 262 * but os::get_temp_directory() is set to "/tmp/" on these 263 * platforms. the java.io.logging packages also makes reference 264 * to java.io.tmpdir. 265 */ 266 tmpdir = "/tmp/"; 267 } 268 /* 269 * Assure that the string returned has a trailing File.separator 270 * character. This check was added because the Linux implementation 271 * changed such that the java.io.tmpdir string no longer terminates 272 * with a File.separator character. 273 */ 274 if (tmpdir.lastIndexOf(File.separator) != (tmpdir.length()-1)) { 275 tmpdir = tmpdir + File.separator; 276 } 277 tmpDirName = tmpdir; 278 } 279 }
なるほど、id:t_yano の言っていた通りの感じになってた。