8
votes

Sous quelles sont les situations de Java Field.Setapestable (True) échoue?

J'ai une situation dans laquelle le code d'un utilisateur lance un illegalAccessException sur un champ accessible par réflexion. Juste avant d'accéder au champ, SetectaSsible (True) est appelé. Donc, il me semblerait que cette méthode échoue silencieusement.

Sous quelles situations cela arriverait-il? Cela pourrait-il avoir quelque chose à voir avec un gestionnaire de sécurité?

Voici l'extrait de code qui cause l'exception: xxx


1 commentaires

Imprimez le message d'exception et StackTrace seraient utiles.


3 Réponses :


0
votes

de la propriété de Java Documentation pour SetAstable () :

SecurityException est soulevé si le drapeau est vrai, mais l'accessibilité de l'un des éléments de la matrice d'entrée peut ne pas être modifié (par exemple, si l'objet Element est un objet constructeur pour la classe de classe). En cas de telle SecurityException, l'accessibilité des objets est défini sur le drapeau pour les éléments de tableau jusqu'à (et à l'exclusion) l'élément pour lequel l'exception s'est produite; L'accessibilité des éléments au-delà (et comprenant) l'élément pour lequel l'exception s'est produite est inchangée.

Malheureusement, ils ne mentionnent rien à propos d'un illegalAccessException.


0 commentaires

6
votes

Cela ne devrait pas être un problème de gestionnaire de sécurité - vous obtiendriez une exception de sécurité ou une sous-classe.

Le code Levelfield.getint (* this *) n'a pas l'air juste ...

Vous devriez passer une instance de messageInfo comme paramètre.

Appelez-vous cela à partir de la classe MessageInfo ? (Pourquoi?!?) Ou une sous-classe de messageInfo ? (Essayer de faire un domaine privé d'une superclasse agir comme si elle est protégée? Est-ce que messageinfo avoir une méthode getlevel () ? Si oui, vous pouvez appeler super. getlevel () pour obtenir la valeur au lieu de tenter cela de cette façon.)

Si ce n'est pas MessageInfo ou une sous-classe, c'est votre problème - vous avez le champ niveau de la classe MessageInfo classe et que vous tentez pour obtenir la valeur de ce champ hors de la classe actuelle. Bien que cela devait lancer un illégalargumentexèce au lieu de illegalAccessException ...

Si c'est vraiment «illegalaccessexeception» - essayez de mettre quelques journalisation à l'intérieur de ce si (Levelfield == null) Block - Assurez-vous qu'il est vraiment exécuté. Le champ est statique - il peut y avoir une autre instance ou une autre méthode définissant une valeur à ce sujet.


3 commentaires

Oui, cette classe est une sous-classe de la classe MessageInfo, qui fait partie d'un cadre que j'utilise. Donc, le champ de niveau est un champ protégé de paquet de messageInfo sans getter, ce qui est donc inaccessible autrement à ma sous-classe. Ce code fonctionne correctement pour beaucoup de nombreux utilisateurs, mais tout simplement pas en particulier. Donc, je me demande s'il pourrait y avoir quelque chose de particulier à propos de cette configuration de cette personne qui rend l'appel échoue ici. C'est ce qui me conduit à penser que cela pourrait éventuellement être un gestionnaire de sécurité, mais je me demande s'il pourrait y avoir autre chose.


Peut-être que cet utilisateur a une version plus récente / ancienne de ce cadre sur la classe de classe? Un où le messageInfo.level n'existe pas ou a un nom différent? P.s. - Quel cadre s'agit-il? Pourrait aider à résoudre ce problème ...


Peut-être, mais peu probable. Le cadre que je décris est la JDT de Eclipse. Et c'est le code que nous utilisons depuis au moins 3.3 (avant que je travaillais sur le projet). Et j'en ai testé cela jusqu'à et y compris Eclipse 3.5.1. Comme décrit par Tom dans la réponse acceptée, je pense que cela pourrait être un problème de filetage.



5
votes

SETPESSIBLE est documenté pour lancer un SecurityException . Notez que la documentation donne des cas où SecurityException sera lancé même s'il n'y a pas de SecurityManager présent. Bien sûr, il peut également échouer en raison d'une exception asynchrone: thread.stop , une exception connexe Nio Buffer ou une erreur JVM.

Le vrai problème avec ce code (autre que celui utilisé par la réflexion) est qu'il existe un champ qui peut être défini pour être partiellement initialisé. Cela provoque une condition de course (vous avez une statique mutable, vous devez donc vous inquiéter des threads (indice, éviter les statiques mutables!)). Un autre thread peut appeler getint sur le même champ avant SETPESSIBLE est appelé. Et comme le questionneur initial semble avoir découvert, ce n'est pas une exception en sécurité non plus. Il serait beaucoup plus sûr et plus clair de configurer le terrain dans une initialiseuse statique.


1 commentaires

Cela mène beaucoup de sens pour moi. Merci. Je ne sais pas si c'est le problème que je vois, mais cela semble possible parce que je sais que plusieurs threads ont été connus pour habiter cette partie du code. Mais même si ce n'est pas le vrai problème, je devrais changer mon code.