To jest właściwie błąd JDK. Zostało to zgłoszone kilkakrotnie na przestrzeni lat, ale dopiero w 8139507 Oracle w końcu poważnie to potraktowało.
Problem dotyczył kodu źródłowego JDK dla WindowsPreferences.java
. W tej klasie oba węzły userRoot
i systemRoot
zostały zadeklarowane jako statyczne, jak w:
/**
* User root node.
*/
static final Preferences userRoot =
new WindowsPreferences(USER_ROOT_NATIVE_HANDLE, WINDOWS_ROOT_PATH);
/**
* System root node.
*/
static final Preferences systemRoot =
new WindowsPreferences(SYSTEM_ROOT_NATIVE_HANDLE, WINDOWS_ROOT_PATH);
Oznacza to, że przy pierwszym odwołaniu do klasy zainicjowane zostaną obie zmienne statyczne, w wyniku czego HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs
nastąpi próba utworzenia klucza rejestru (= drzewo systemowe), jeśli jeszcze nie istnieje.
Więc nawet jeśli użytkownik podejmie wszelkie środki ostrożności w swoim własnym kodzie i nigdy nie dotknie drzewa systemowego ani nie będzie do niego odwoływał, wówczas JVM nadal będzie próbował utworzyć instancję systemRoot
, powodując ostrzeżenie. To interesujący subtelny błąd.
Wprowadzono poprawkę dotyczącą źródła JDK w czerwcu 2016 r. I jest ona częścią Java9 i późniejszych wersji. Istnieje również backport dla Java8, który jest w wersji u202.
To, co widzisz, jest naprawdę ostrzeżeniem z wewnętrznego rejestratora JDK. To nie jest wyjątek. Uważam, że ostrzeżenie można bezpiecznie zignorować ... chyba że kod użytkownika rzeczywiście chce preferencji systemowych, ale tak się rzadko zdarza.
Informacje o bonusie
Błąd nie ujawniał się w wersjach wcześniejszych niż Java 1.7.21, ponieważ do tego czasu instalator JRE tworzył HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs
dla ciebie klucz rejestru , co skutecznie ukrywałoby błąd. Z drugiej strony nigdy tak naprawdę nie było wymagane uruchomienie instalatora, aby mieć JRE na twoim komputerze, a przynajmniej nie było to intencją Sun / Oracle. Jak zapewne wiesz, Oracle od .tar.gz
wielu lat dystrybuuje środowisko JRE dla Windows w formacie.