Access to non-public classes in the sun.awt package [in particular: FetcherInfo]
Question:
I have some performance issues in my application and the bottleneck is sun.awt.image.ImageFetcher.run
and I cannot get (more) meaningful information from the profiler. So I thought it would be nice to look at the work that ImageFetcher is doing.
I was unable to access the class FetcherInfo
that contains all the assignments ImageFetcher
. To get an instance FetcherInfo
, I have to call FetcherInfo.getFetcherInfo()
.
I created a class in a package sun.awt.image
(only in my project, I didn't mess with rt.jar).
To get FetcherInfo
i use:
try{
for(Method method : FetcherInfo.class.getDeclaredMethods()){
method.setAccessible(true);
if(method.getName().equals("getFetcherInfo")){
m = method;
}
}
}catch (Exception e){
e.printStackTrace();
}
FetcherInfo info = null;
try {
info = (FetcherInfo) m.invoke(null);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
And I am getting an exception: Exception in thread "IMAGE-FETCHER-WATCHER" java.lang.IllegalAccessError: tried to access class sun.awt.image.FetcherInfo from class sun.awt.image.FetcherDebug
And the stack trace points to:
for(Method method : FetcherInfo.class.getDeclaredMethods()){
The same exception was thrown:
FetcherInfo.class.getMethod("getFetcherInfo");
So, anyone have any ideas how:
- Get an ImageFetcher instance
- Find out what images are loading.
Decision
The problem was that I put my class in a package sun.java.awt
so I can access protected packages without putting it in rt.jar
, and an exception was thrown by typing ImageFetcher.class
.
source to share
To access non-accessible members use setAccessible(true)
. (Without the presence of a security manager, sun.*
there is no block on the block to be used with reflection.)
import java.lang.reflect.Method;
public class Access {
public static void main(String[] args) throws Exception {
Class<?> imageFetcher = Class.forName("sun.awt.image.FetcherInfo");
for (Method method : imageFetcher.getDeclaredMethods()) {
;
}
Method method = imageFetcher.getDeclaredMethod("getFetcherInfo");
method.setAccessible(true);
Object fetcher = method.invoke(null);
System.err.println(fetcher);
}
}
source to share