解决 java.util.prefs.BackingStoreException 报错问题

启动tomcat后,发现有个warnning

信息如下

java.util.prefs.FileSystemPreferences checkLockFile0ErrorCode 

Warning: Could not locksystem prefs. Unix error code 0. 
java.util.prefs.FileSystemPreferences syncWorld 

Warning: Couldn't flush system prefs: java.util.prefs.BackingStoreException: Couldn't get file lock.

这个warnning每半个分钟出现一次,虽然不是什么特别严重的问题,但是我还是决定看看。


首先找到java.util.prefs.FileSystemPreferences syncWorld  这个方法

  private static void syncWorld() {
        /*
         * Synchronization necessary because userRoot and systemRoot are
         * lazily initialized.
         */
        Preferences userRt;
        Preferences systemRt;
        synchronized(FileSystemPreferences.class) {
            userRt   = userRoot;
            systemRt = systemRoot;
        }

        try {
            if (userRt != null)
                userRt.flush();
        } catch(BackingStoreException e) {
            getLogger().warning("Couldn't flush user prefs: " + e);
        }

        try {
            if (systemRt != null)
                systemRt.flush();
        } catch(BackingStoreException e) {
            getLogger().warning("Couldn't flush system prefs: " + e);
        }
    }


看起来应该是flush 这个方法的抛出异常了

再往里跟

    public void flush() throws BackingStoreException {
        if (isRemoved())
            return;
        sync();
    }


应该是sync的里面报错

public synchronized void sync() throws BackingStoreException {
        boolean userNode = isUserNode();
        boolean shared;

        if (userNode) {
            shared = false; /* use exclusive lock for user prefs */
        } else {
            /* if can write to system root, use exclusive lock.
               otherwise use shared lock. */
            shared = !isSystemRootWritable;
        }
        synchronized (isUserNode()? userLockFile:systemLockFile) {
           if (!lockFile(shared))
               throw(new BackingStoreException("Couldn't get file lock."));


最后一行的错误信息在日志里打出来了

这里看起来应该是lockfile返回的是false,于是进去

private boolean lockFile(boolean shared) throws SecurityException{
        boolean usernode = isUserNode();
        int[] result;
        int errorCode = 0;
        File lockFile = (usernode ? userLockFile : systemLockFile);
        long sleepTime = INIT_SLEEP_TIME;
        for (int i = 0; i < MAX_ATTEMPTS; i++) {
            try {
                  int perm = (usernode? USER_READ_WRITE: USER_RW_ALL_READ);
                  result = lockFile0(lockFile.getCanonicalPath(), perm, shared);

                  errorCode = result[ERROR_CODE];
                  if (result[LOCK_HANDLE] != 0) {
                     if (usernode) {
                         userRootLockHandle = result[LOCK_HANDLE];
                     } else {
                         systemRootLockHandle = result[LOCK_HANDLE];
                     }
                     return true;
                  }
            } catch(IOException e) {
//                // If at first, you don't succeed...
            }

            try {
                Thread.sleep(sleepTime);
            } catch(InterruptedException e) {
                checkLockFile0ErrorCode(errorCode);
                return false;
            }
            sleepTime *= 2;
        }
        checkLockFile0ErrorCode(errorCode);
        return false;
    }



这个方法,根据要锁的是用户文件还是系统文件,去锁对应的文件,最多重试到最大次数之后返回false


因为报的是系统文件无法锁住,我就看了一下系统文件在哪里赋值


private static void setupSystemRoot() {
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            public Void run() {
                String systemPrefsDirName =
                  System.getProperty("java.util.prefs.systemRoot","/etc/.java");
                systemRootDir =
                     new File(systemPrefsDirName, ".systemPrefs");
                // Attempt to create root dir if it does not yet exist.
                if (!systemRootDir.exists()) {
                    // system root does not exist in /etc/.java
                    // Switching  to java.home
                    systemRootDir =
                                  new File(System.getProperty("java.home"),
                                                            ".systemPrefs");
                    if (!systemRootDir.exists()) {
                        if (systemRootDir.mkdirs()) {
                            getLogger().info(
                                "Created system preferences directory "
                                + "in java.home.");
                            try {
                                chmod(systemRootDir.getCanonicalPath(),
                                                          USER_RWX_ALL_RX);
                            } catch (IOException e) {
                            }
                        } else {
                            getLogger().warning("Could not create "
                                + "system preferences directory. System "
                                + "preferences are unusable.");
                        }
                    }
                }
                isSystemRootWritable = systemRootDir.canWrite();
                systemLockFile = new File(systemRootDir, ".system.lock");
                systemRootModFile =
                               new File (systemRootDir,".systemRootModFile");
                if (!systemRootModFile.exists() && isSystemRootWritable)
                try {
                    // create if does not exist.
                    systemRootModFile.createNewFile();
                    int result = chmod(systemRootModFile.getCanonicalPath(),
                                                          USER_RW_ALL_READ);
                    if (result !=0)
                        getLogger().warning("Chmod failed on " +
                               systemRootModFile.getCanonicalPath() +
                              " Unix error code " + result);
                } catch (IOException e) { getLogger().warning(e.toString());
                }
                systemRootModTime = systemRootModFile.lastModified();
                return null;
            }
        });
    }


看到这里明白了,如果jvm没有设systemroot的话,那是默认etc下面的那个.java文件夹,如果这个文件夹存在,就用这个,如果不存在,那就用java.home的这个

我去我的etc下面看了一下,果然有.java这个隐藏文件夹,我给他干掉之后就没有那个警告了。或者设定上systemroot 这个参数


http://www-01.ibm.com/support/docview.wss?uid=swg21515420 这篇文章讲的是user pref cannot lock这个问题


  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值