I have a situation where a user's code is throwing an IllegalAccessException
on a field accessed by reflection. Just before accessing the field, setAccessible(true)
is called. So, it would seem to me that this method is silently failing.
Under what situations would this happen? Could this have something to do with a security manager?
Here is the code snippet that is causing the exception:
private static Field levelField;
public int getLevel() {
try {
if (levelField == null) {
levelField = MessageInfo.class.getDeclaredField("level");
levelField.setAccessible(true);
}
return levelField.getInt(this); // <-- IllegalAccessException thrown here
} catch (Exception e) {
handleException(e);
}
return ICompilationUnit.NO_AST;
}
It shouldn't be a security manager issue - you'd get a SecurityException or subclass.
The code levelField.getInt(*this*)
doesn't look right...
You should be passing an instance of MessageInfo
as the parameter.
Are you calling this from within the MessageInfo
class? (why?!?) or a subclass of MessageInfo
? (Trying to make a private field of a superclass act as if it's protected? Does MessageInfo
have a getLevel()
method? If so, you could call super.getLevel()
to get the value instead of attempting it this way.)
If it's not MessageInfo
or a subclass, that's your problem - you have the level
field of the MessageInfo
class and you're attempting to get the value of that field off the current class. Though this should be throwing an IllegalArgumentExeception
instead of IllegalAccessException
...
If it's really 'IllegalAccessExeception' - try putting some logging inside that if (levelField == null)
block - make sure it's really being exececuted. The field is static - there may be some other instance or method setting a value on it.
setAccessible
is documented to throw a SecurityException
. Note that the documentation gives cases where SecurityException
will be thrown even if there is no SecurityManager
present. Of course it may also fail due to an asynchronous exception: Thread.stop
, NIO buffer related exception or a JVM error.
The real problem with this code (other than that it uses reflection) is that there is a field that can be set to be partially initialised. This causes a race condition (you have a mutable static, therefore you need to worry about threads (hint, avoid mutable statics!)). Another thread may call getInt
on the same Field
before setAccessible
is called. And as the original questioner appears to have found out, it isn't exception safe either. It would be much safer and clearer to set up the field in a static initialiser.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With