Accedi alle classi non pubbliche nel pacchetto sun.awt [in particolare: FetcherInfo]
-
03-07-2019 - |
Domanda
Domanda:
Ho qualche problema di prestazioni nella mia app - e il collo di bottiglia è sun.awt.image.ImageFetcher.run
e non riesco a ottenere (più) informazioni significative dal profiler. Quindi ho pensato che sarebbe stato bello guardare ai lavori che ImageFetcher stava facendo.
Non sono riuscito ad accedere alla classe FetcherInfo
, che contiene tutti i lavori ImageFetcher
. Per ottenere l'istanza FetcherInfo
devo chiamare FetcherInfo.getFetcherInfo ()
.
Ho creato la classe nel pacchetto sun.awt.image
(proprio nel mio progetto, non ho armeggiato con rt.jar).
Per ottenere FetcherInfo
uso:
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();
}
E ottengo un'eccezione: Eccezione nella discussione " IMAGE-FETCHER-WATCHER " java.lang.IllegalAccessError: tentato di accedere alla classe sun.awt.image.FetcherInfo dalla classe sun.awt.image.FetcherDebug
E la traccia dello stack punta a:
for(Method method : FetcherInfo.class.getDeclaredMethods()){
La stessa eccezione è stata sollevata da:
FetcherInfo.class.getMethod("getFetcherInfo");
Quindi chiunque ha qualche idea su come:
- Ottieni l'istanza di ImageFetcher
- Scopri quali immagini vengono caricate
SOLUTION
Il problema era che ho inserito la mia classe nel pacchetto sun.java.awt
per ottenere l'accesso ai membri protetti dal pacchetto, senza metterlo in rt.jar
, ed è stata emessa un'eccezione quando abbiamo chiamato ImageFetcher.class
.
Soluzione
Per accedere ai membri non accessibili utilizzare setAccessible (true)
. (Senza un gestore della sicurezza presente, non vi è alcun blocco sulle classi sun. *
da utilizzare con 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);
}
}