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 ответов:
к сожалению, большинство ответов вы тут не правы ... хотя бы немного. В том смысле, что лечится симптом, а не причина.
давайте. 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, поскольку это, похоже, ограничение длины ключа (я не верил, что это связано, пока не попробовал).
загрузка содержит инструкции и объясняет:
из-за ограничений контроля импорта некоторых стран, версия файлы политики JCE, которые входят в состав среды выполнения Java Окружающая среда, или JRE (TM), среда 8 позволяет" сильной", но ограниченной криптографии быть используемый. Этот пакет загрузки (тот, который включает этот файл README) предоставляет файлы политики "неограниченная сила", которые не содержат ограничения по стойкости.
Это, по-видимому, относится и к ключам реестра