web-dev-qa-db-fra.com

Java: échec de Java.util.Preferences

Mon programme enregistre les données de clé de produit cryptées sur l'ordinateur avec la classe Java.util.Preferences (préférences système, pas utilisateur). Le problème est que, sous Windows et Linux (non testé sur OSX, mais c'est probablement le même problème), si je n'exécute pas le programme avec Sudo ou avec les privilèges d'administrateur, il émet une exception ou un avertissement chaque fois qu'il tente de lire ou sauvegarder les données.

De toute évidence, obliger l'utilisateur à exécuter le programme avec des privilèges d'administrateur serait peu pratique. De manière optimale, j'aimerais que le système d'exploitation demande l'autorisation à l'utilisateur.

C'est assez stupide et supprime la moitié de l'objectif de Preferences. Comment cela peut-il être corrigé?

Voici un résumé de ce dont j'ai besoin : J'ai besoin que mon programme demande l'autorisation du système d'exploitation pour enregistrer les paramètres du système.


Voici les informations d'erreur

Voici l'erreur lorsque j'essaie de lire un nœud (car le nœud n'existe pas):

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.

Et voici ce qui se passe lorsque j'essaie d'écrire sur un nœud:

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.
63
Jonah

Malheureusement, la plupart des réponses que vous avez obtenues sont erronées ... au moins légèrement. En ce sens que le symptôme est traité, pas la cause.

Résumons. Les préférences Java ont deux "arbres": le arbre utilisateur et le arbre système . Vous pouvez écrire votre propre backend dans les préférences Java (appelé magasin de sauvegarde), mais peu de développeurs le font. Vous obtenez donc le magasin de sauvegarde par défaut du JDK. Sur une plate-forme Windows, cela signifie le registre Win, plus précisément:

  • L'arborescence utilisateur est écrite dans HKEY_CURRENT_USER\Software\JavaSoft\Prefs (l'utilisateur du système d'exploitation toujours a un accès en écriture ici)
  • L'arborescence system est écrite dans HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs (seul un utilisateur de système d'exploitation possédant des privilèges administrateur a un accès en écriture ici).

En résumé: tant que votre code ne tente pas d'utiliser l'arborescence du système, tout devrait bien se passer et vous ne devriez pas avoir à vous soucier de l'attribution de privilèges au niveau du système d'exploitation. L'arborescence système est destinée à "tous les utilisateurs de l'hôte" et l'arborescence est destinée à l'utilisateur connecté. Dans votre cas, je suis convaincu que vous pouvez vous contenter de l’arbre utilisateur, c’est vraiment votre solution. Ne jouez pas avec les privilèges, exécutez-vous en tant qu'administrateur et quoi encore.

.... mais il y a plus. Supposons que votre code ne touche pas délibérément l’arborescence système des préférences Java, comme indiqué. Vous allez alors toujours voir cet avertissement sous Windows:

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

Alors, quoi de neuf? Est-ce que je t'ai donné le mauvais conseil? Pas vraiment. Restez avec moi.

En plongeant dans le code source du JDK, vous verrez que 0x80000002 signifie HKLM, c’est-à-dire l’endroit dans le registre Win qui ne devrait pas être touché. Votre code ne fait jamais référence à l'arborescence du système et pourtant vous voyez toujours cet avertissement! (À ce stade, vous devez déchirer tous vos cheveux ... comme je l'ai fait)

Eh bien, c’est l’une des rares occasions où il y a vraiment un bug JDK . Vous pouvez en savoir plus à ce sujet dans cette réponse par moi-même, que je vous encourage à lire si vous souhaitez savoir pourquoi des bugs subtils peuvent rester non détectés dans le JDK pendant des années. Le bogue existe depuis JDK 1.4 mais n’a été corrigé que récemment et n’a pas encore été rétroporté dans JDK 8.

Meilleur conseil

  • Assurez-vous que votre code fait uniquement référence à l'arborescence utilisateur, pas à l'arborescence système. Il n’est que juste que le système d’exploitation exige toute sorte de données confidentielles pour que vous puissiez écrire sur un emplacement système. Si vous vraiment avez besoin d'écrire dans un tel emplacement, il n'y a pas d'autre solution que d'affecter des privilèges, de s'exécuter en tant qu'administrateur ou non.
  • Ignorer l'avertissement. Il disparaîtra une fois que vous êtes sur Java 9 ou lorsque Oracle décide de reporter le correctif dans Java 8. Cet avertissement peut être ignoré en toute sécurité. 
  • Sinon, vous pouvez essayer d'ignorer l'avertissement par programme. Il provient de la plate-forme Logger du JDK, ce qui devrait fonctionner, même si je ne l'ai pas essayé moi-même:

    Sun.util.logging.PlatformLogger platformLogger = PlatformLogger.getLogger("Java.util.prefs");
    platformLogger.setLevel(PlatformLogger.Level.OFF);
    
35
peterh

Ce lien est un travail pour moi:

Résolution du problème La solution consiste à vous connecter en tant que administrator et à créer la clé HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs.

41
morrxy

Il est possible de changer les droits d'accès des entrées de registre. Si vous accordez des droits d'accès complets à HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs à tout le monde, tout le monde verra le même ensemble de préférences et tout le monde pourra les modifier globalement. Je suis conscient que ce n'est pas une solution pour les logiciels installés par les clients, mais peut être utile pour quelqu'un. 

11
kuester2000

Modification de la réponse en fonction des commentaires reçus… .. Cette solution est probablement excessive mais ...

  • Je vous suggère de changer votre magasin pour écrire dans un fichier au lieu du registre ( exemple )
  • Beaucoup de produits basés sur Java sont livrés avec leur propre JVM. Ils le font pour pouvoir s'exécuter avec un fichier de stratégie personnalisé (ce qui serait nécessaire dans votre cas pour écrire dans un emplacement commun) et économiser sur les problèmes d'assistance (tels que l'utilisation de machines virtuelles obsolètes/non testées)
5
qwerty

Surtout avec Windows 7, la machine virtuelle Java n'a pas par défaut le droit d'écrire dans le registre Windows où le magasin de support de Java.util.prefs.preferences se trouve sous MS-Windows.

Lors de l'exécution du transformateur ReverseXSL, ou même du programme de test Regex, des erreurs telles que: Impossible d'ouvrir/de créer le nœud racine prefs Software\JavaSoft\Prefs à la racine 0x80000002. Windows RegCreateKeyEx

Cela empêche l'enregistrement d'une licence. Cela n'empêche pas le logiciel d'effectuer des transformations en mode logiciel libre.

Résoudre le problème consiste simplement à accorder les autorisations nécessaires à la clé racine du registre en question.

Exécutez regedit.exe en tant qu'administrateur (regedit.exe se trouve dans le répertoire racine du système d'exploitation c:\Windows) . Accédez à la clé HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs. Faites un clic droit pour définir les autorisations. Cochez la case Contrôle total pour le ou les utilisateurs devant exécuter le logiciel reverseXSL.

3
guest

Il suffit d'exécuter l'application en tant qu'administrateur ou, si vous utilisez Eclipse, d'exécuter Eclipse en tant qu'administrateur.

2
Ashu

Ce correctif a finalement été corrigé, en janvier 2019, dans le kit de développement Java SE 8u202. 

Il s’agit de la mise à jour du jeu de correctifs (PSU), par opposition à la mise à jour critique du correctif (CPU), 8u201. La différence est expliquée ici . (La page utilise Java 7 à titre d'exemple, mais elle fait passer le message.) 

Le téléchargement se trouve plus bas sur la page "Java SE Development Kit 8". ( https://www.Oracle.com/technetwork/Java/javase/downloads/jdk8-downloads-2133151.html )

1
Katrina Eaton

La réponse de peterh déjà élaboré sur le fond, mais je cherchais un correctif et l'ai trouvé!

Puisque vous ne pouvez pas toucher le PlatformLogger lui-même, vous devez annuler son message: 

// 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);

De cette façon, l'avertissement ennuyeux a disparu sans laisser de traces. Notez que vous devez le faire uniquement au moment où vous référencez l'API de préférences pour la première fois dans votre programme.

1
Xerus

La solution pour moi n’était pas évidente: il s’agissait de mettre à jour mes fichiers jar de sécurité cryptographique d’Oracle, car il semble y avoir une restriction de longueur de clé (je ne pensais pas que c’était lié, jusqu’à ce que je l’essaye).

Télécharger depuis le site Oracle

Le téléchargement contient des instructions et explique:

En raison des restrictions imposées par certains pays sur le contrôle des importations, la version de les fichiers de règles JCE regroupés dans Java Runtime Environment, ou JRE (TM), 8 environnement permettent une cryptographie "forte" mais limitée.. utilisé. Ce package de téléchargement (comprenant ce fichier README) fournit des fichiers de politique "de force illimitée" qui ne contiennent pas restrictions sur les forces de cryptographie.

Cela s'applique apparemment aussi aux clés de registre

0
Nick Cardoso

Le correctif consiste à exécuter JMeter en tant qu'administrateur, il créera la clé de registre pour vous, puis vous pourrez redémarrer JMeter en tant qu'utilisateur normal et vous ne recevrez plus l'avertissement. Site officiel JMeter - modifications

0
Arun Girdhar