Подтвердить что ты не робот

Java: java.util.Preferences Failed

Моя программа сохраняет зашифрованные данные ключа продукта на компьютер с классом java.util.Preferences (системные настройки, а не пользователь). Проблема заключается как в Windows, так и в Linux (они не тестировались в OSX, но, вероятно, это одно и то же), если я не запускаю программу с помощью sudo или с правами администратора, она испускает исключение или предупреждение всякий раз, когда пытается для чтения или сохранения данных.

Очевидно, что требовать от пользователя запуска программы с правами администратора было бы непрактично. Оптимально, я бы хотел, чтобы операционная система запрашивала у пользователя разрешение.

Это довольно глупо и удаляет половину цели Preferences. Как это можно зафиксировать?

Вот сводка, в которой я нуждаюсь. Мне нужно, чтобы моя программа запрашивала разрешение от операционной системы для сохранения настроек системы.


Вот информация об ошибке

Здесь ошибка, когда я пытаюсь прочитать node (потому что node не существует):

Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences <init>
WARNING: Could not create windows registry node Software\JavaSoft\Prefs\myapp at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.
Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences WindowsRegOpenKey1
WARNING: Trying to recreate Windows registry node Software\JavaSoft\Prefs\myapp at root 0x80000002.
Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences openKey
WARNING: Could not open windows registry node Software\JavaSoft\Prefs\myapp at root 0x80000002. Windows RegOpenKey(...) returned error code 2.
Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences WindowsRegOpenKey1
WARNING: Trying to recreate Windows registry node Software\JavaSoft\Prefs\myapp\subpackage at root 0x80000002.
Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences openKey
WARNING: Could not open windows registry node Software\JavaSoft\Prefs\myapp\subpackage at root 0x80000002. Windows RegOpenKey(...) returned error code 2.

И вот что происходит, когда я пытаюсь написать node:

Mar 18, 2011 9:43:11 AM java.util.prefs.WindowsPreferences WindowsRegOpenKey1
WARNING: Trying to recreate Windows registry node Software\JavaSoft\Prefs\myapp\subpackage at root 0x80000002.
Mar 18, 2011 9:43:11 AM java.util.prefs.WindowsPreferences openKey
WARNING: Could not open windows registry node Software\JavaSoft\Prefs\myapp\subpackage at root 0x80000002. Windows RegOpenKey(...) returned error code 2.
4b9b3361

Ответ 1

К сожалению, большинство ответов, которые вы получили здесь, ошибочны... хотя бы слегка. В том смысле, что симптом лечится, а не причина.

Пусть повторяется. Предпочтения Java имеют два "дерева": дерево дерево и системное дерево. Вы можете написать свой собственный бэкэнд на Java Preferences (называемый хранилищем резервных копий), но мало разработчиков, поэтому вы получаете хранилище резервных копий по умолчанию JDK. На платформе Windows это означает Win Registry, а именно:

  • Дерево записано в HKEY_CURRENT_USER\Software\JavaSoft\Prefs (пользователь ОС всегда имеет доступ на запись здесь)
  • Системное дерево записано в HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs (только пользователь ОС с правами администратора имеет доступ на запись здесь)

Вкратце: до тех пор, пока ваш код не пытается использовать системное дерево, вы должны быть в порядке и не должны путаться с назначением привилегий на уровне ОС. Системное дерево предназначено для "всех пользователей на хосте", а дерево пользователей предназначено для конкретного пользователя, зарегистрированного в системе. В вашем случае я уверен, что вам может хватить дерево пользователя, так что это действительно ваше решение. Не переходите к привилегиям, работая как администратор, а что нет.

.... но там больше. Предположим, что ваш код намеренно не касается дерева системных настроек Java, как указано. Затем вы увидите это предупреждение в Windows:

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

Так что происходит? Я дал вам неправильный совет? На самом деле, нет. Оставайтесь со мной.

Дайвинг в исходный код JDK вы увидите, что 0x80000002 означает HKLM, то есть место в Win Registry, которое не следует трогать. Ваш код никогда не ссылается на системное дерево, и все же вы все еще видите это предупреждение!?? (На этом этапе вы должны разорвать все свои волосы... как я это сделал)

Ну, это один из редких случаев, когда действительно существует ошибка JDK. Вы можете прочитать об этом в этом ответе, который я рекомендую вам прочитать, если вас интересует, почему тонкие ошибки могут оставаться незамеченными в JDK в течение многих лет. Ошибка существует с JDK 1.4, но только недавно была исправлена ​​и еще не была передана в JDK 8.

Лучший совет

  • Убедитесь, что ваш код ссылается только на дерево пользователя, а не на дерево системы. Справедливо, что ОС требует, чтобы все виды привилегий записывались в общесистемное местоположение. Если вам действительно нужно писать в такое место, тогда действительно нет другого решения, кроме как назначать привилегированных лиц, выполняющих роль администратора или нет.
  • Игнорировать предупреждение. Он исчезнет, ​​когда вы на Java 9, или когда Oracle решает выполнить резервное копирование исправления ошибок в Java 8. Предупреждение можно смело игнорировать.
  • В качестве альтернативы вы можете попытаться программно игнорировать предупреждение. Он исходит от JDK Platform Logger, поэтому что-то подобное должно работать, хотя я сам не пробовал:

    sun.util.logging.PlatformLogger platformLogger = PlatformLogger.getLogger("java.util.prefs");
    platformLogger.setLevel(PlatformLogger.Level.OFF);
    

Ответ 2

Эта ссылка работает для меня:

Решение проблемы Работа вокруг - это войти в систему как administrator и создать ключ HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs

Ответ 3

Можно изменить права доступа к записям реестра. Если вы разрешаете полный доступ к HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs всем, каждый увидит один и тот же набор предпочтений, и каждый сможет изменить их по всему миру. Я знаю, что это не решение для программного обеспечения, установленного клиентами, но оно может быть полезно для кого-то.

Ответ 4

Изменение ответа на основе обратной связи. Это решение, вероятно, слишком велико, но...

  • Я предлагаю вам изменить свой магазин для записи в файл вместо реестра (пример)
  • Многие продукты на базе Java поставляются со своей собственной JVM. Они делают это так, чтобы они могли запускаться с настраиваемым файлом политики (который понадобился бы в вашем случае для записи в общее место) и сэкономить на проблемах поддержки (например, используется устаревшая/непроверенная JVM).

Ответ 5

В частности, в Windows 7 JVM по умолчанию не имеет права на запись в реестр Windows, где хранилище резервных копий для java.util.prefs.preferences находится в MS-Windows.

При выполнении трансформатора ReverseXSL или даже программы тестера Regex можно получить такие ошибки, как: Не удалось открыть/создать prefs root node Software\JavaSoft\Prefs в корне 0x80000002. Windows RegCreateKeyEx

Это предотвращает регистрацию лицензии. Это не мешает программе выполнять преобразования в режиме свободного программного обеспечения.

Фиксирование проблемы - это просто вопрос предоставления необходимых прав на ключ root root.

Запустите regedit.exe как администратор (regedit.exe находится в корневом каталоге операционной системы c:\Windows). Перейдите в раздел HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs. Щелкните правой кнопкой мыши, чтобы установить разрешения. Проверьте отметку в поле "Полный контроль" для пользователей (пользователей), которым необходимо выполнить программное обеспечение reverseXSL.

Ответ 6

Просто запустите приложение как администратор или используйте eclipse, запустите eclipse как администратор.

Ответ 7

Ответ peterh уже был разработан на фоне, но я искал исправление и нашел его!

Поскольку вы не можете касаться самого PlatformLogger, вы должны аннулировать его сообщение:

// get rid of the bugged Preferences warning
PrintStream err = System.err;
System.setErr(new PrintStream(new OutputStream() {
    public void write(int b) {}
}));
Preferences PREFS = Preferences.userNodeForPackage(Settings.class);
System.setErr(err);

Таким образом, раздражающее предупреждение исчезло, не оставив никаких следов. Обратите внимание, что вам нужно сделать это только в том месте, где вы впервые ссылаетесь на API настроек в своей программе.

Ответ 8

Исправление состоит в том, чтобы запустить JMeter в качестве администратора, он создаст для вас раздел реестра, затем вы можете перезапустить JMeter как обычный пользователь и больше не будете иметь предупреждения. Официальный сайт JMeter - изменения

Ответ 9

Решение для меня не было очевидным - нужно было обновить мои блоки безопасности для криптографии от Oracle, поскольку это, по-видимому, ограничение на длину ключа (я не думал, что это было связано, пока я не попробовал).

Загрузка с веб-сайта Oracle

Загрузка содержит инструкции и объясняет:

Из-за ограничений контроля импорта некоторых стран, версия файлы политики JCE, которые включены в среду выполнения Java Runtime Environment, или среда JRE (TM), 8 позволяют "сильную", но ограниченную криптографию используемый. Этот пакет загрузки (тот, который включает этот файл README) предоставляет файлы политики "неограниченной силы", которые не содержат ограничения на криптографические сильные стороны.

Это, очевидно, также относится к ключам реестра.

Ответ 10

Наконец, это было исправлено в январе 2019 года в Java SE Development Kit 8u202.

Это обновление набора исправлений (PSU), в отличие от критического обновления исправлений (CPU), 8u201. Разница объясняется здесь. (Страница использует Java 7 в качестве примера, но она все понимает.)

Загрузку можно найти ниже на странице "Java SE Development Kit 8". (https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)

Ответ 11

Перейдите в свой реестр и создайте JavaSoft\Prefs\myapp в разделе HKEY_LOCAL_MACHINE-->SOFTWARE

Создайте ключевое имя как Prefs и создайте дополнительный ключ как myapp, это решит проблему.