java.util.Prefs抛出BackingStoreException-为什么?

java.util.Prefs抛出BackingStoreException-为什么?,java,preferences,Java,Preferences,我有一个系统可以缓存启动时SOAP调用的微小/简单结果 我需要实例能够在启动时重新加载缓存(以防SOAP服务失效),并且还需要处理使用此缓存文件的多个实例的可能性 我选择使用java.util.prefs,但java的内置自动同步线程间歇性失败(1%的时间使用默认的JVM 30s备份存储同步),引发以下异常: Jan 8, 2010 12:30:07 PM java.util.prefs.FileSystemPreferences syncWorld WARNING: Couldn't flus

我有一个系统可以缓存启动时SOAP调用的微小/简单结果

我需要实例能够在启动时重新加载缓存(以防SOAP服务失效),并且还需要处理使用此缓存文件的多个实例的可能性

我选择使用
java.util.prefs
,但java的内置自动同步线程间歇性失败(1%的时间使用默认的JVM 30s备份存储同步),引发以下异常:

Jan 8, 2010 12:30:07 PM java.util.prefs.FileSystemPreferences syncWorld
WARNING: Couldn't flush user prefs: java.util.prefs.BackingStoreException: Couldn't get file lock.
我怀疑,但这是在1.5(tiger-b40)中修复的,我们在这个框中的Java5是“1.5.0_16-b02”

我现在怀疑这可能是因为我们有多个JVM共享这个备份存储,尽管这似乎不会发生在我们的其他机器上

有人能证实这一点吗? 如果有风险,风险是什么

如果我的方法有缺陷,我应该使用什么作为替代方案?

“我现在怀疑这可能是因为我们有多个JVM共享此备份存储”

这绝对是事实! 如果两个JVM试图同时锁定文件,那么您将看到这一点

具体细节将取决于锁的类型、操作系统和文件系统


您可能希望尝试将导致此问题的操作包装到try/catch块中,然后在操作失败时重试该操作。

不使用首选项,只需使用任何可序列化映射,并创建一个非常简单的缓存类,将其序列化并反序列化为随机生成的临时文件名即可(第一次初始化时生成的文件名)。由于它只是一个缓存,您可以捕获任何异常,并在异常发生时将缓存重置回初始状态,因此它将从原始数据源(您的SOAP服务)重新获取。因此,如果您不想的话,无需担心serialVersionUID或任何兼容性问题。

我在jetty上遇到了相同的问题。我发现以下方法修复了该问题

.systemPrefs
添加到JRE目录中,并为正在运行进程的用户提供访问权限

完成后,转到Jetty目录并打开
start.ini
文件

-
Djava.util.prefs.userRoot={user's home directory}

-
Djava.util.prefs.systemRoot={user's home directory}


添加完这些行后,我重新启动了jetty,发现错误消失了。

给出一些代码,不要期望我们猜测这肯定与多个JVM尝试使用同一个文件有关。人们倾向于使用数据库来集中多个进程同时共享和修改的数据
java.util.prefs
API是一个火鸡。我建议忽略它,使用其他人实际使用的东西,比如数据库。实际上我根本不想共享数据,我只是想创建一个便宜的配置(通过SOAP调用)对于投票支持cache.DB的人来说,cache.DB的分量太重了Bozho:没有代码,这是一个失败的Java系统线程!谢谢你的回复。不幸的是,问题是Java首选项的同步线程超出了我们的控制,因此无法捕获异常。这里有一个很好的评论:保存了死链接:问题是我需要实例能够在启动时重新加载其缓存(以防SOAP服务失效),并且还可以处理多个实例使用此缓存文件的可能性。我将添加到OPI guess,它通过更改特定JRE使用的存储来工作,以避免与您必须运行的其他JRE发生冲突。感谢共享