Не могу записать настройки Java в Windows 10

Я пытаюсь запустить программу, которая ищет Java предпочтения в Windows 10, используя JDK 10.0.2. Если он находит их в системном узле, он пытается скопировать их в собственный узел пользователя, а затем пользователь может изменить их по своему вкусу. Мне не везет ни в чтении, ни в письме. Я пробовал несколько разных JDK в версии 8, а затем установил 10, исходя из теории, что она может работать лучше, но это не так.

Моя программа — это старая игра, которую я написал несколько лет назад. В последний раз, когда я запускал его в 2012 году, он работал нормально.

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

    import java.util.prefs.BackingStoreException;
    import java.util.prefs.Preferences;

    public class Prefs01 {

    public static void main( final String[] args ) throws BackingStoreException {

    Preferences systemRoot = Preferences.systemRoot(); 

    Preferences preferences = systemRoot.node("fuzz"); 

    systemRoot.put( "foo", "bar" );

    systemRoot.put( "baz", "lolz" );
    System.out.println( "-------------------------------" );

    String[] keys = preferences.keys();
    for( String key : keys ) {
        System.out.println( key );
    }

    System.out.println( "-------------------------------" );

    keys = systemRoot.keys();
    for( String key : keys ) {
        System.out.println( key );
    }
  }
}

Результаты

Preferences systemRoot = Preferences.systemRoot(); 

Отладчик показывает, что systemRoot стоит "/" после этого оператора; ошибок пока нет.

Preferences preferences = systemRoot.node("fuzz"); 

Консоль выдает такое сообщение:

Oct 01, 2018 5:05:24 PM java.util.prefs.WindowsPreferences <init>
WARNING: Could not create windows registry node Software\JavaSoft\Prefs\fuzz at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.  

systemRoot.put( "foo", "bar" );

Консоль выдает это сообщение и трассировку стека:

01 октября 2018 г. 17:09:38 java.util.prefs.WindowsPreferences openKey ПРЕДУПРЕЖДЕНИЕ. Не удалось открыть узел реестра Windows Software\JavaSoft\Prefs в корневом каталоге 0x80000002. Windows RegOpenKey(...) вернул код ошибки 5. Исключение в потоке "main" java.lang.SecurityException: не удалось открыть узел реестра Windows Software\JavaSoft\Prefs в корневом каталоге 0x80000002: доступ запрещен в java.prefs/java.util. prefs.WindowsPreferences.openKey(WindowsPreferences.java:553) в java.prefs/java.util.prefs.WindowsPreferences.openKey(WindowsPreferences.java:515) в java.prefs/java.util.prefs.WindowsPreferences.openKey(WindowsPreferences. java:501) в java.prefs/java.util.prefs.WindowsPreferences.putSpi(WindowsPreferences.java:652) в java.prefs/java.util.prefs.AbstractPreferences.put(AbstractPreferences.java:263) в Prefs01.main (Превс01.java:13)

Основываясь на сообщениях об ошибках, которые я получаю, у меня сложилось впечатление, что у меня есть какая-то проблема с авторизацией Windows: я не авторизован делать то, что я пытаюсь сделать в реестре Windows. Для меня это не имеет смысла, потому что на этой машине есть только один UAC, и он является администратором; Я не знаю, как запустить эту программу под другим UAC, даже если на машине есть другой UAC.

Может ли кто-нибудь пролить свет на то, что здесь происходит не так, и что мне нужно сделать, чтобы это исправить?


person Henry    schedule 01.10.2018    source источник
comment
Вы должны убедиться, что запускаете программу Java от имени администратора. Попробуйте открыть командную строку от имени администратора и запустить код Java оттуда. А еще лучше, не связывайтесь с системными настройками, если в этом нет абсолютной необходимости. Просто используйте пользовательские настройки.   -  person Andreas    schedule 02.10.2018
comment
Как я могу быть кем-то, кроме администратора, если у меня есть только одна учетная запись пользователя на компьютере, и она является администратором?   -  person Henry    schedule 02.10.2018
comment
Это не совсем то, как должен использоваться класс Preferences. Я рекомендую прочитать документацию класса. Особенно актуально: «Обычным приложениям не нужно вызывать какие-либо из этих методов, которые можно идентифицировать по тому факту, что они объявлены как генерирующие BackingStoreException». Если вы хотите указать внутренние значения по умолчанию, сохраните их как импортируемый ресурс XML в вашем приложении.   -  person VGR    schedule 02.10.2018
comment
@Andreas: Что бы это ни стоило, я установил путь к JDK и попытался выполнить программу из командной строки (после ее компиляции с помощью javac) и получил те же ошибки и трассировку стека.   -  person Henry    schedule 02.10.2018
comment
@ Генри Вы открыли командную строку, щелкнув правой кнопкой мыши и выбрав «Запуск от имени администратора». Не имеет значения, вошли ли вы в систему как пользователь с правами администратора, вам все равно нужно сказать «Запуск от имени администратора». См. статьи о Windows UAC, например в Википедии   -  person Andreas    schedule 02.10.2018
comment
@VGR: я в замешательстве. Я был вдали от Java в течение нескольких лет, но когда я учился использовать Preferences, вскоре после их выхода, я был уверен, что использую их точно по назначению. Изменилось ли это за прошедшие годы? Если да, можете ли вы указать мне на что-нибудь, что объясняет, как настройки должны выполняться сейчас? Когда я смотрел, я ничего не видел об импортируемом XML в API, но это мог быть API JDK 7....   -  person Henry    schedule 02.10.2018
comment
@ Генри Это не проблема Java, а проблема безопасности Windows. Windows значительно усилила безопасность со времен Windows XP, и вы сталкиваетесь с расширенными блоками безопасности, добавленными Windows UAC.   -  person Andreas    schedule 02.10.2018
comment
@Andreas: я попробовал запустить от имени администратора, и на этот раз программа сработала. Я прочитал статью в Википедии, которую вы предложили, но не полностью ей следовал; в нем много незнакомого. Что делают типичные пользователи Java, особенно в Eclipse, чтобы заставить свои программы работать в условиях ограничений, налагаемых Windows? Это было бы действительно полезно знать.   -  person Henry    schedule 02.10.2018
comment
В настоящее время вы используете системные настройки; переключение на пользовательские настройки вообще помогает?   -  person Slaw    schedule 02.10.2018
comment
@Slaw Я изменил все вхождения system на user в коде и запустил его в Eclipse, и все выполнилось нормально, без сообщений об ошибках. Является ли это естественным способом сказать мне, чтобы я просто вообще не использовал системный узел и просто поместил все настройки в пользовательский узел? Это то, что делают другие пользователи Java? Я должен верить, что у других Java-разработчиков есть простой подход, который отлично работает и отлично работал со времен Vista, когда WIndows начала возиться с безопасностью реестра....   -  person Henry    schedule 02.10.2018
comment
У меня недостаточно опыта, чтобы рассказать, как сообщество Java в целом использует Preferences API. Все, что я могу сказать, это то, что в прошлом у меня были проблемы с использованием системных настроек, и мне помогло переключение на пользовательские настройки. Во всяком случае, в большинстве случаев пользовательские настройки имели больше смысла в контексте моего приложения.   -  person Slaw    schedule 02.10.2018
comment
С момента появления Preferences API обычное использование класса Preferences всегда ограничивалось методами get и put (а также userNodeForPackage, импортом/экспортом и некоторыми другими вещами). Документация описывает это довольно хорошо; если метод выдает BackingStoreException, он предназначен для внутреннего использования.   -  person VGR    schedule 02.10.2018


Ответы (1)


Как заявили некоторые из комментаторов, запуск «От имени администратора», вероятно, решит проблему.

Однако основная причина вашей проблемы указана в этой ошибке и в вашем коде:

Preferences systemRoot = Preferences.systemRoot(); 
...
WARNING: Could not open windows registry node Software\JavaSoft\Prefs at root 0x80000002

В текущих реализациях JDK systemRoot эквивалентно HKEY_LOCAL_MACHINE (как и 0x80000002). По умолчанию пользователи не имеют права записи здесь без использования UAC.

Чтобы решить эту проблему, вам лучше всего изменить свой код, чтобы использовать Preferences.userRoot(), который обращается к узлам реестра под HKEY_CURRENT_USER, который обычно доступен для записи.

person Rocketeer    schedule 31.03.2020