|
|
|
@ -449,31 +449,37 @@ public class ClassLoaderCommand extends AnnotatedCommand {
|
|
|
|
|
|
|
|
|
|
// 以树状列出ClassLoader的继承结构
|
|
|
|
|
private static List<ClassLoaderVO> processClassLoaderTree(List<ClassLoaderVO> classLoaders) {
|
|
|
|
|
List<ClassLoaderVO> rootClassLoaders = new ArrayList<ClassLoaderVO>();
|
|
|
|
|
List<ClassLoaderVO> parentNotNullClassLoaders = new ArrayList<ClassLoaderVO>();
|
|
|
|
|
List<ClassLoaderVO> rootClassLoaders = new ArrayList<>();
|
|
|
|
|
Map<String, List<ClassLoaderVO>> childMap = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
// 分离根节点和非根节点,并构建父子关系映射
|
|
|
|
|
for (ClassLoaderVO classLoaderVO : classLoaders) {
|
|
|
|
|
if (classLoaderVO.getParent() == null) {
|
|
|
|
|
rootClassLoaders.add(classLoaderVO);
|
|
|
|
|
} else {
|
|
|
|
|
parentNotNullClassLoaders.add(classLoaderVO);
|
|
|
|
|
childMap.computeIfAbsent(classLoaderVO.getParent(), k -> new ArrayList<>()).add(classLoaderVO);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (ClassLoaderVO classLoaderVO : rootClassLoaders) {
|
|
|
|
|
buildTree(classLoaderVO, parentNotNullClassLoaders);
|
|
|
|
|
// 构建树
|
|
|
|
|
for (ClassLoaderVO root : rootClassLoaders) {
|
|
|
|
|
buildTree(root, childMap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rootClassLoaders;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void buildTree(ClassLoaderVO parent, List<ClassLoaderVO> parentNotNullClassLoaders) {
|
|
|
|
|
for (ClassLoaderVO classLoaderVO : parentNotNullClassLoaders) {
|
|
|
|
|
if (parent.getName().equals(classLoaderVO.getParent())){
|
|
|
|
|
parent.addChild(classLoaderVO);
|
|
|
|
|
buildTree(classLoaderVO, parentNotNullClassLoaders);
|
|
|
|
|
private static void buildTree(ClassLoaderVO parent, Map<String, List<ClassLoaderVO>> childMap) {
|
|
|
|
|
List<ClassLoaderVO> children = childMap.get(parent.getName());
|
|
|
|
|
if (children != null) {
|
|
|
|
|
for (ClassLoaderVO child : children) {
|
|
|
|
|
parent.addChild(child);
|
|
|
|
|
buildTree(child, childMap);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static Set<ClassLoader> getAllClassLoaders(Instrumentation inst, Filter... filters) {
|
|
|
|
|
Set<ClassLoader> classLoaderSet = new HashSet<ClassLoader>();
|
|
|
|
|
|
|
|
|
|