C'è un modo per ottenere quali classi ha caricato un ClassLoader?
-
07-07-2019 - |
Domanda
Sto cercando di implementare alcuni test unitari per un vecchio framework. Sto tentando di deridere il livello del database. Sfortunatamente il nostro framework è un po 'vecchio e non utilizza le migliori pratiche, quindi non c'è una chiara separazione delle preoccupazioni. Sono un po 'preoccupato che il tentativo di deridere il livello del database potrebbe far sì che la JVM carichi un numero enorme di classi che non verranno nemmeno utilizzate.
Non capisco molto bene i caricatori di classi, quindi questo potrebbe non essere un problema. C'è un modo per fare un picco in tutte le classi che un particolare ClassLoader ha caricato per provare cosa sta succedendo sotto il cofano?
Soluzione
Ti avvisiamo che usando
java -verbose
Produrrà un'enorme quantità di output. Registra l'output in un file e quindi utilizza grep. Se hai il filtro "tee" puoi provare questo:
java -verbose | tee classloader.log
grep class classloader.log
Altri suggerimenti
Puoi creare il tuo Classloader personale e usarlo per caricare durante il test unitario. Chiedi al tuo Classloader personalizzato di stampare ciò che sta facendo.
O se vuoi solo sapere quali classi vengono caricate, fai:
java -verbose:class
Non ne sono sicuro. Ma c'è un modo in cui vedo che potrebbe essere fatto. Forse è eccessivamente ridicolo. Puoi provare gli aspetti e inserire un punto di riferimento per loadclass. Forse anche l'argomento jvm -verbose potrebbe essere utile.
In alternativa, per un particolare caricatore di classi come hai menzionato, puoi utilizzare questo frammento di codice. Se lo desideri, modifica il valore della variabile obj.
Object obj = this;
ClassLoader classLoader = obj.getClass().getClassLoader();
File file = new File("classloderClasses.txt");
if (file.exists()) {
file.delete();
}
if (classLoader != null) {
try {
Class clClass = classLoader.getClass();
while (clClass != ClassLoader.class) {
clClass = clClass.getSuperclass();
}
java.lang.reflect.Field classesField = clClass.getDeclaredField("classes");
classesField.setAccessible(true);
Vector classes = (Vector) classesField.get(classLoader);
FileOutputStream fos = new FileOutputStream("classloderClasses.txt", true);
fos.write(("******************** " + classLoader.toString() + " ******************** " + "\n").getBytes());
fos.write(Arrays.toString(classes.toArray()).getBytes());
fos.close();
} catch (Exception exception) {
exception.printStackTrace();
// TODO
}
}
Utilizzare l'opzione -Xlog
per configurare o abilitare la registrazione con il framework di registrazione unificato Java Virtual Machine (JVM). Il vantaggio è che puoi scrivere i risultati nel file di testo
Sinossi
-Xlog[:[what][:[output][:[decorators][:output-options [,...]]]]]
Nella sintassi della registrazione unificata,
-verbose: class
è uguale a-Xlog:class+load=info
Ad esempio
java -Xlog:class+load=info:classloaded.txt