Если ваш вопрос заключается в том, как проиллюстрировать или визуализировать иерархию загрузчика классов для объектов, то вы можете пройти каждый класс classloader в коде. Вы упомянули, что вы используете заводным, так что пример будет выглядеть так:
def showObjectClassLoaderHierarchy(Object obj) {
def classLoader = showClassLoaderHierarchy(obj.getClass().getClassLoader());
showClassLoaderHierarchy(classLoader);
}
def showClassLoaderHierarchy(ClassLoader loader) {
if (loader != null) {
println "Classloader: " + loader.hashCode();
while (loader.getParent() != null) {
loader = loader.getParent();
println " Child of: " + loader.hashCode();
}
}
}
Я думаю, что вы найдете в вашем коде, два объекта данных фактически не загружается из тех же загрузчика классов, поэтому у них есть различные статические переменные.
я собрал образец, который имеет
- Main (загружается из родительского загрузчика)
- DataObj со статической String (нагруженной также из родительского загрузчика)
- Loada, который создает экземпляр копии DataObj (загружается из ребенок загрузчика классов A)
- LoadB, который инициализирует копию DataObj (загружается из ребенка B загрузчика классов)
Я вижу, что в то время как LoadA и LoadB имеют разные загрузчики классов, DataObj и статическая переменная исходят от обычного загрузчика классов.
Полный код по адресу: https://github.com/lucasmcgregor/groovy_classloader_test
Главный объект в заводной:
import java.lang.ClassLoader;
import java.net.URLClassLoader;
import java.net.URL;
def showObjectClassLoaderHierarchy(Object obj) {
def classLoader = showClassLoaderHierarchy(obj.getClass().getClassLoader());
showClassLoaderHierarchy(classLoader);
}
def showClassLoaderHierarchy(ClassLoader loader) {
if (loader != null) {
println "Classloader: " + loader.hashCode();
while (loader.getParent() != null) {
loader = loader.getParent();
println " Child of: " + loader.hashCode();
}
}
}
println "Setting up child classLoaders A and B...";
def URL[] urlsA = [new URL("file:///tmp/cla/")];
def classLoaderA = new URLClassLoader(urlsA, this.getClass().getClassLoader());
def URL[] urlsB = [new URL("file:///tmp/clb/")];
def classLoaderB = new URLClassLoader(urlsB, this.getClass().getClassLoader());
println "Classloader A heirachry:";
showClassLoaderHierarchy(classLoaderA);
println "Classloader B: ";
showClassLoaderHierarchy(classLoaderB);
println "";
println "Now loading Load classes A and B from seperate classloaders:";
def loadA = classLoaderA.loadClass("LoadA").newInstance();
def loadB = classLoaderB.loadClass("LoadB").newInstance();
print "LoadA: heirachry";
showObjectClassLoaderHierarchy(loadA);
print "LoadB: heirachry";
showObjectClassLoaderHierarchy(loadB);
println "";
println "Now pulling the data objects from both and comparing classloders and static data: ";
def dobjA = loadA.getDataObj();
def dobjB = loadB.getDataObj();
println "dataA static field:" + dobjA.getData();
println "dataA static field hashcode: " + dobjA.getData().hashCode();
println "dataA hashcode: " + dobjA.hashCode();
println "dataA classloader: ";
showObjectClassLoaderHierarchy(dobjA);
println "dataB static field: " + dobjB.getData();
println "dataB static field hashcode: " + dobjB.getData().hashCode();
println "dataB hashcode: " + dobjB.hashCode();
println "dataB classLoader:";
showObjectClassLoaderHierarchy(dobjB);
Результаты:
Setting up child classLoaders A and B...
Classloader A heirachry:
Classloader: 1926764753
Child of: 1163157884
Child of: 1022308509
Classloader B:
Classloader: 846238611
Child of: 1163157884
Child of: 1022308509
Now loading Load classes A and B from seperate classloaders:
LoadA: heirachryClassloader: 1926764753
Child of: 1163157884
Child of: 1022308509
LoadB: heirachryClassloader: 846238611
Child of: 1163157884
Child of: 1022308509
Now pulling the data objects from both and comparing classloders and static data:
dataA static field:Loaded By B
dataA static field hashcode: 1828548084
dataA hashcode: 2083117811
dataA classloader:
Classloader: 1163157884
Child of: 1022308509
dataB static field: Loaded By B
dataB static field hashcode: 1828548084
dataB hashcode: 157683534
dataB classLoader:
Classloader: 1163157884
Child of: 1022308509
Вы видите, что Loada и LoadB оба имеют разные загрузчики классов, но они совместно использовать родительский загрузчик классов.
Родительский загрузчик классов загружает DataObj для обоих экземпляров LoadA.dataObj и LoadB.dataObj.
LoadA.dataObj и LoadB.dataObj имеют разные хэш-коды.
Однако LoadA.dataObj.data и LoadB.dataObj.data имеют одинаковый хэш-код, потому что это статический объект. Они также имеют одинаковую ценность. LoadB создает экземпляр dataObj last и устанавливает строку «Loaded By B»
Вы уверены, что и «класс A», и «класс B» разговаривают с «тот же самый класс' Data', что и в классе 'Data', загруженном одним загрузчиком классов? Если 'Data' загружается разными загрузчиками классов, а' class A' и 'class B' разговаривают с разными версиями, то ожидается то, что вы видите. Это очень зависит от иерархии загрузчика классов, поэтому немного этого контекста поможет. – mystarrocks
@mystarrocks спасибо за отзывы, которые уже помогли. Кажется, я действительно не получаю одну и ту же ссылку на класс. Я соответствующим образом обновил свой вопрос. Спасибо! – WeSt
Связаны ли эти классы с приложением, которое работает на сервере? Различные контейнеры используют различные методы загрузки классов. – mystarrocks