refactor(classloader): 重构类加载器并优化黑名单处理
- 使用 CopyOnWriteArrayList 替代 ArrayList 以提高线程安全- 优化类加载逻辑,避免类重复加载 - 黑名单添加更多系统和第三方库前缀 - 修复类循环依赖问题 - 简化代码结构,提高可读性
This commit is contained in:
@@ -26,6 +26,7 @@ public class Main {
|
||||
private static final String[] AUTHOR = new String[]{
|
||||
"tzdwindows 7"
|
||||
};
|
||||
|
||||
/** 我是总任务数 **/
|
||||
public int totalTasks = 1;
|
||||
/** 我是当前任务数 **/
|
||||
|
||||
@@ -1,30 +1,39 @@
|
||||
package com.axis.innovators.box.plugins;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* 自定义类加载器,装载CorePlugins
|
||||
* @author tzdwindows 7
|
||||
*/
|
||||
public class BoxClassLoader extends URLClassLoader {
|
||||
private static final List<IClassTransformer> CLASS_TRANSFORMS = new ArrayList<>();
|
||||
private static final List<IClassTransformer> CLASS_TRANSFORMS = new CopyOnWriteArrayList<>();
|
||||
private static final List<String> CLASS_BLACKLIST = new ArrayList<>();
|
||||
private static final List<String> CLASS_LOADING_LIST = new ArrayList<>();
|
||||
private static final List<Class<?>> CLASS_LOADING_LIST_OBJECT = new ArrayList<>();
|
||||
private static final List<String> CLASS_LOADING_LIST = Collections.synchronizedList(new ArrayList<>());
|
||||
private static final List<Class<?>> CLASS_LOADING_LIST_OBJECT = new CopyOnWriteArrayList<>();
|
||||
|
||||
static {
|
||||
// 添加黑名单,避免加载核心类
|
||||
CLASS_BLACKLIST.add("java.");
|
||||
CLASS_BLACKLIST.add("javax.");
|
||||
CLASS_BLACKLIST.add("sun.");
|
||||
Collections.addAll(CLASS_BLACKLIST,
|
||||
"java.", "javax.", "sun.", "com.sun.", "jdk.",
|
||||
"org.xml.", "org.w3c.", "org.apache.",
|
||||
"javax.management.", "javax.swing."
|
||||
);
|
||||
}
|
||||
|
||||
public BoxClassLoader(ClassLoader parent) {
|
||||
super(new URL[]{}, parent);
|
||||
try {
|
||||
PluginLoader.loadCorePlugin();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to load core plugin", e);
|
||||
}
|
||||
}
|
||||
|
||||
public BoxClassLoader(URL[] urls, ClassLoader parent) {
|
||||
@@ -36,77 +45,56 @@ public class BoxClassLoader extends URLClassLoader {
|
||||
super.addURL(url);
|
||||
}
|
||||
|
||||
//@Override
|
||||
//protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
||||
// synchronized (getClassLoadingLock(name)) {
|
||||
// // 1. 检查类是否已加载
|
||||
// Class<?> c = findLoadedClass(name);
|
||||
// if (c != null) {
|
||||
// return c;
|
||||
// }
|
||||
//
|
||||
// // 2. 检查黑名单
|
||||
// if (isBlacklisted(name)) {
|
||||
// return super.loadClass(name, resolve);
|
||||
// }
|
||||
//
|
||||
// // 3. 尝试自定义加载
|
||||
// try {
|
||||
// c = findClass(name);
|
||||
// } catch (ClassNotFoundException e) {
|
||||
// // 4. 自定义加载失败则委托给父加载器
|
||||
// c = super.loadClass(name, resolve);
|
||||
// }
|
||||
//
|
||||
// if (resolve) {
|
||||
// resolveClass(c);
|
||||
// }
|
||||
// return c;
|
||||
// }
|
||||
//}
|
||||
@Override
|
||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
||||
synchronized (getClassLoadingLock(name)) {
|
||||
Class<?> loadedClass = findLoadedClass(name);
|
||||
if (loadedClass != null) return loadedClass;
|
||||
|
||||
if (isBlacklisted(name)) {
|
||||
return getParent().loadClass(name);
|
||||
}
|
||||
|
||||
try {
|
||||
Class<?> c = findClass(name);
|
||||
if (resolve) resolveClass(c);
|
||||
return c;
|
||||
} catch (ClassNotFoundException e) {
|
||||
return super.loadClass(name, resolve);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||
// 检查是否在黑名单中
|
||||
if (isBlacklisted(name)) {
|
||||
throw new ClassNotFoundException("Class is blacklisted: " + name);
|
||||
}
|
||||
synchronized (getClassLoadingLock(name)) {
|
||||
if (CLASS_LOADING_LIST.contains(name)) {
|
||||
throw new ClassCircularityError(name + " circular loading detected");
|
||||
}
|
||||
|
||||
// 检查是否正在加载
|
||||
if (CLASS_LOADING_LIST.contains(name)) {
|
||||
throw new ClassNotFoundException("Class is already loading: " + name);
|
||||
}
|
||||
CLASS_LOADING_LIST.add(name);
|
||||
try {
|
||||
byte[] clazzByte = getClassBytes(name);
|
||||
for (IClassTransformer transformer : CLASS_TRANSFORMS) {
|
||||
byte[] transformed = transformer.transform(name, transformer.getClass().getName(), clazzByte);
|
||||
if (transformed != null) clazzByte = transformed;
|
||||
}
|
||||
|
||||
// 读取类字节码
|
||||
byte[] clazzByte;
|
||||
try {
|
||||
clazzByte = getClassBytes(name);
|
||||
} catch (IOException e) {
|
||||
throw new ClassNotFoundException("Failed to load class bytes: " + name, e);
|
||||
}
|
||||
|
||||
// 应用类转换器
|
||||
for (IClassTransformer transformer : CLASS_TRANSFORMS) {
|
||||
byte[] transformed = transformer.transform(name, transformer.getClass().getName(), clazzByte);
|
||||
if (transformed != null) {
|
||||
clazzByte = transformed;
|
||||
Class<?> clazz = defineClass(name, clazzByte, 0, clazzByte.length);
|
||||
CLASS_LOADING_LIST_OBJECT.add(clazz);
|
||||
return clazz;
|
||||
} catch (IOException e) {
|
||||
throw new ClassNotFoundException("Class byte loading failed", e);
|
||||
} finally {
|
||||
CLASS_LOADING_LIST.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
// 定义类
|
||||
CLASS_LOADING_LIST.add(name);
|
||||
Class<?> clazz = defineClass(name, clazzByte, 0, clazzByte.length);
|
||||
CLASS_LOADING_LIST_OBJECT.add(clazz);
|
||||
return clazz;
|
||||
}
|
||||
|
||||
private byte[] getClassBytes(String className) throws IOException, ClassNotFoundException {
|
||||
String path = className.replace('.', '/') + ".class";
|
||||
URL classUrl = getResource(path);
|
||||
if (classUrl == null) {
|
||||
throw new ClassNotFoundException("Class not found: " + className);
|
||||
}
|
||||
try (InputStream is = classUrl.openStream()) {
|
||||
try (InputStream is = getResourceAsStream(path)) {
|
||||
if (is == null) throw new ClassNotFoundException(className);
|
||||
return is.readAllBytes();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user