Java: java.утиль.Предпочтения Не


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

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

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

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


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

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

Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences <init>
WARNING: Could not create windows registry node SoftwareJavaSoftPrefsmyapp 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 SoftwareJavaSoftPrefsmyapp at root 0x80000002.
Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences openKey
WARNING: Could not open windows registry node SoftwareJavaSoftPrefsmyapp 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 SoftwareJavaSoftPrefsmyappsubpackage at root 0x80000002.
Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences openKey
WARNING: Could not open windows registry node SoftwareJavaSoftPrefsmyappsubpackage at root 0x80000002. Windows RegOpenKey(...) returned error code 2.

и это то, что происходит, когда я пытаюсь написать в узел:

Mar 18, 2011 9:43:11 AM java.util.prefs.WindowsPreferences WindowsRegOpenKey1
WARNING: Trying to recreate Windows registry node SoftwareJavaSoftPrefsmyappsubpackage at root 0x80000002.
Mar 18, 2011 9:43:11 AM java.util.prefs.WindowsPreferences openKey
WARNING: Could not open windows registry node SoftwareJavaSoftPrefsmyappsubpackage at root 0x80000002. Windows RegOpenKey(...) returned error code 2.
10 61

10 ответов:

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

давайте. Java Preferences имеет два "дерева":пользователь дерево и дерево системы. Вы можете написать свой собственный бэкэнд в Java Preferences (называемый резервным хранилищем), но это делают немногие разработчики, поэтому вы получаете резервное хранилище JDK по умолчанию. На платформе Windows это означает реестр Win, больше в частности:
  • The пользователь дерево написано в HKEY_CURRENT_USER\Software\JavaSoft\Prefs (пользователь ОС всегда имеет доступ на запись здесь)
  • The дерево системы написано в HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs (только для пользователей ОС с администратора privs имеет доступ на запись здесь)

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

.... но это еще не все. Предположим, что ваш код намеренно не касается системного дерева настроек 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, которое не должно быть затронуто. Ваш код никогда не ссылается на системное дерево, и все же вы все еще видите это предупреждение !?? (В этот момент Вы, должно быть, вырываете все свои волосы ... как и я)

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

лучшие советы

  • убедитесь, что ваш код ссылается только на дерево пользователей, а не на системное дерево. Это справедливо, что ОС требует всех видов Priv для вас, чтобы писать в общесистемном месте. Если вы действительно нужно писать в такое место, тогда действительно нет другого решения, кроме назначения privs, выполнения от имени администратора или чего-то еще.
  • игнорируем предупреждение. Он исчезнет, как только вы окажетесь на Java 9 или когда Oracle решит вернуть исправление ошибки в Java 8. Предупреждение можно смело игнорировать.
  • в качестве альтернативы вы можете попытаться программно игнорировать предупреждение. Это происходит от регистратора платформы JDK, поэтому что-то вроде этого должно работать, хотя я и не пробовал сам:

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

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

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

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

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

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

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

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

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

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

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

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

ответ 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 настроек в своей программе.

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

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

скачать с сайта Oracle

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

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

Это, по-видимому, относится и к ключам реестра

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

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