Чтение и запись с/на Java Preferences происходит неудачно в новых Windows 8,

У меня есть приложение Java, которое читает с Preferences, используя:

Preferences prefs = Preferences.userNodeForPackage(MyClass.class);
prefs.get((String)key, "");

На новой машине Windows 8 это не удается:

WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs 
at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.

Код ошибки 5 запрещен.

Я не могу найти ничего, что я делаю неправильно. Поиски Google и SO дают старые результаты, относящиеся только к Windows Vista/7, где один ошибочно использовал systemRoot ( Как написать параметры системы с помощью Java? Могу ли я вызвать UAC? ​​).

Ошибка может быть "вылечена", создав HKLM/Software/JavaSoft/Prefs и установив разрешения для HKLM/Software/JavaSoft, как указано здесь Java: java.util.Preferences Failed. Но это не то, что я могу потребовать от моих пользователей, когда они устанавливают программу.

Итак, я ищу лучшее решение. Мое последнее стремление - просто написать в файл, но Я бы хотел избежать этого. Это также похоже на Я пытаюсь использовать Java Prefences из XML БЕЗ использования реестра Windows, но я вижу сообщение, связанное с реестром, но оно было отклонено без ответа.

В настоящее время я подозреваю, что ошибка JVM от Win8...

Вопросы

  • Кто-нибудь знает о решении, которое не связано с написанием файлов?
  • Почему один и тот же код отлично работает в Windows 7, но в Windows 8 он не работает?

Ответ 1

Недавно я начал замечать одно и то же предупреждение и думал, что это означает, что реестр не может быть записан. Но при ближайшем рассмотрении я заметил, что все настройки, которые успешно обновлены в HKEY_CURRENT_USER, в любом случае. Поэтому мне стало любопытно, почему я вижу это предупреждение.

Оказалось, что виновником является эта статическая переменная-член: WindowsPreferences.systemRoot

Похоже, что Java пытается инициализировать WindowsPreferences.systemRoot на всякий случай, когда она используется позже программой, и что инициализация, очевидно, терпит неудачу, если программа не запущена как администратор.

Поскольку вы используете Preferences.userNodeForPackage(), вам никогда не понадобится systemRoot, поэтому вы можете смело игнорировать это предупреждение.

Конечно, это ужасная практика, которую Java пытается инициализировать systemRoot, когда она не запрашивается.

Обновление: Я тестировал эту проблему в различных версиях Java и пришел к выводу, что эта ошибка была введена в Java 1.7.0_21. Он отлично работал в Java 1.7.0_17 просто потому, что установщик этой версии создаст папку "Pref" в реестре! Конечно, даже в этой версии, если вы хотите удалить "Pref" из реестра, это перестанет работать, поэтому с самого начала Oracle это было глупое решение. Я напишу отчет об ошибке.

Обновление 2: Предупреждающее сообщение не является ошибкой. Кажется, это предполагаемое поведение: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6809488