| Author |
Why get IllegalAccessException for Iterator.next in reflection?
|
Dan Bizman
Ranch Hand
Joined: Feb 25, 2003
Posts: 387
|
|
I'm using reflection to deal with a number of objects sent into my program. Everything has worked fine for every object up till now. However, when a java.util.Iterator is sent in and the method "next" called, I get the exception: Is my only solution to call "setAccessible( true )" on the method "next" prior to invoking it? I don't like that option but it seems to be the only choice. Well, I suppose I could get the class' interfaces, loop through them and if it's public look for the method I want (and if not, call setAccessible). Both options don't seem great. What I don't get is that the iterator returned has a public method "next" and yet in reflection somehow I'm unable to call it? That makes no sense: it's public! [ March 31, 2008: Message edited by: Dan Bizman ] [ March 31, 2008: Message edited by: Dan Bizman ]
|
 |
Jim Yingst
Wanderer
Sheriff
Joined: Jan 30, 2000
Posts: 18670
|
|
|
Most likely, this error message is misleading, and the problem is not with the public method, but with the non-public class java.util.AbstractList$Itr. The $ tells us that Itr is some sort of nested class defined within AbstractList. If this class is not public, then reflection won't let you access its methods, even if the methods are public. You have two basic options: (a) call setAccessible(true) on the class (not the method), or (b) use the Class instance java.util.Iterator.class (representing a public interface), rather than java.util.AbstractList$Itr (representing a non-public class). Both of these define a public method next(), but only Iterator.class will let you call its methods without using setAccessible(true).
|
"I'm not back." - Bill Harding, Twister
|
 |
Dan Bizman
Ranch Hand
Joined: Feb 25, 2003
Posts: 387
|
|
Originally posted by Jim Yingst: Most likely, this error message is misleading, and the problem is not with the public method, but with the non-public class java.util.AbstractList$Itr. The $ tells us that Itr is some sort of nested class defined within AbstractList. If this class is not public, then reflection won't let you access its methods, even if the methods are public. You have two basic options: (a) call setAccessible(true) on the class (not the method), or (b) use the Class instance java.util.Iterator.class (representing a public interface), rather than java.util.AbstractList$Itr (representing a non-public class). Both of these define a public method next(), but only Iterator.class will let you call its methods without using setAccessible(true).
Thanks for the response. I can't use "Iterator" as I don't know the class of the objects coming in, it's all through reflection, so this is just one case. I can't predict beforehand what it'll be. So I guess I'll do the setAccessible... I have a question however: why do i call setAccessible() on the class and not the method? It does work to call it on the method, so is this bad for a reason? Thanks!
|
 |
Jim Yingst
Wanderer
Sheriff
Joined: Jan 30, 2000
Posts: 18670
|
|
[Dan]: I can't use "Iterator" as I don't know the class of the objects coming in, it's all through reflection, so this is just one case. I can't predict beforehand what it'll be. So I guess I'll do the setAccessible... Another possibility is to use Class methods getSuperclass() and getInterfaces() to discover all classes and interfaces that are extended or implemented, and if one of those is public and declares the method you're trying to use, use that class/interface instead. On the other hand if using setAccessible() works for you, that's probably easier. [Dan]: I have a question however: why do i call setAccessible() on the class and not the method? It does work to call it on the method, so is this bad for a reason? Well, if that works, then do it. I'm working from vague memories of a problem I saw long ago. Maybe I'm misremembering, or maybe the JDK behaves differently now. For the problem I'm remembering, the root cause was that the class was non-public, so it makes at least intuitive sense to modify the class to be accessible, not the method. But hey, whatever works.
|
 |
 |
|
|
subject: Why get IllegalAccessException for Iterator.next in reflection?
|
|
|