我的猜测是错误的,与答案无关。这个问题不再有效。请参阅my answer 。很抱歉这个糟糕的问题。
Tl;dr 版本
为什么 Java 进程无法找到某个文件,直到另一个进程(创建该文件的进程)完成执行。这可以解决吗?
加长版本
我有一个应用程序需要自行重新启动(它只需要重新启动,好吗?)。第一次,它创建一个文件,然后在那里序列化一个对象。这是通过 FileOutputStream
完成的/ObjectOutputStream
组合,如下所述:
private static File serializeBootstrapInfoIntoFile(
final BootstrapInfo info) throws IOException {
final File tempFile = File.createTempFile("BobBootstrapInfo", null);
final FileOutputStream fos = new FileOutputStream(tempFile);
final ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(info);
// just being thorough
oos.flush();
oos.close();
fos.flush();
fos.close();
return tempFile;
}
在此之后,我使用 System.exec()
创建另一个 java 进程。 -call,我将返回的 tempFile
的绝对路径传递给它作为系统属性。然后,另一个 java 进程应该打开该文件,并反序列化包含的对象。第一个进程保持 Activity 状态,直到生成的进程退出,因为它处理新进程的输出/错误流。
但是,问题是第二个进程似乎找不到该文件,并且总是在 FileNotFoundException
中终止。在反序列化期间(我已经用 file.exists()
确认了这一点)。
事后手动检查,该文件确实存在。另外,如果我手动运行传递给 System.exec()
的完全相同的命令行,运行良好。因此,我猜测第一个进程以某种方式设法从新进程中隐藏文件,或者无法实际将文件写入文件系统,即使流被刷新并关闭。我也尝试过 Thread.sleep(10000)
在第一个线程上,让 IO 操作完成,但这没有一点帮助。
我做错了什么吗?或者这是 Java 的事情,或者可能是 OSX 的事情(我正在使用 atm 运行)?
评论回复
我运行的是 OS X 10.6.3,Java 版本是 1.6.0_20。
System.exec()
参数是
java
-classpath
/var/folders/dr/drDlHsguGvq0zF2Jtgn4S++++TI/-Tmp-/bob7168396245507677201.tmp:/Users/wolfie/Documents/workspace/Bob/dist/lib/junit.jar:/Users/wolfie/Documents/workspace/Bob/dist/lib/bob.jar
-Dcache.location="/var/folders/dr/drDlHsguGvq0zF2Jtgn4S++++TI/-Tmp-/BobBootstrapInfo4944987280015634213.tmp"
com.github.wolfie.bob.Bob
其中每一行都是字符串数组中的一个元素。 /var/folders/dr/drDlHsguGvq0zF2Jtgn4S++++TI/-Tmp-/BobBootstrapInfo4606780571989099166.tmp
-file 是已创建的文件,并由另一个线程读取。 envp
和dir
参数是 null
.
整个堆栈跟踪是:
Exception in thread "main" com.github.wolfie.bob.BootstrapError: java.io.FileNotFoundException: "/var/folders/dr/drDlHsguGvq0zF2Jtgn4S++++TI/-Tmp-/BobBootstrapInfo4606780571989099166.tmp" (No such file or directory)
at com.github.wolfie.bob.Bob.getBootstrapInfo(Bob.java:186)
at com.github.wolfie.bob.Bob.run(Bob.java:138)
at com.github.wolfie.bob.Bob.main(Bob.java:95)
Caused by: java.io.FileNotFoundException: "/var/folders/dr/drDlHsguGvq0zF2Jtgn4S++++TI/-Tmp-/BobBootstrapInfo4606780571989099166.tmp" (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(FileInputStream.java:106)
at com.github.wolfie.bob.Bob.deserializeBootstrapInfoFromFile(Bob.java:265)
at com.github.wolfie.bob.Bob.getBootstrapInfo(Bob.java:184)
... 2 more
最佳答案
从问题中看不到答案:我像这样定义了系统属性:
-Dcache.location="/foo/file.ext"
但该属性应该是相反的
-Dcache.location=/foo/file.ext
即没有引号。显然,当从命令行传递完全相同的参数时,这一点被忽略,可能是因为 Bash 以与 JVM 不同的方式处理它们。
很抱歉这个问题问得不好。
关于进程 fork 时的 Java 文件管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3126948/