我建议为插件编写一个自定义类加载器,它将包的存在隐藏在com.example使用该类加载器加载的类中。通常类加载器委托给它们的父级,但是有几种实现方式只是部分或根本不这样做。我相信例如蚂蚁使用这种技术。当使用这样的类加载器加载时,任何与禁止功能链接的类都将无法加载。或者,如果实现使用了惰性链接,并且确实加载成功,那么在执行禁止代码期间它仍然会失败。
拒绝您的插件链接时访问被禁止的包后,您可以使用 SecurityManager 通过反射拒绝运行时访问,也可以拒绝创建可能用于绕过您的新类加载器。
class RestrictingClassLoader extends URLClassLoader {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if (!name.startsWith("com.example.") || name.startsWith("com.example.api."))
return super.loadClass(name);
return findClass(name);
}
}
class RestrictingSecurityManager extends SecurityManager {
private boolean isRestricted() {
for (Class<?> cls: getClassContext())
if (cls.getClassLoader() instanceof RestrictingClassLoader)
return true;
return false;
}
// Implement other checks based on isRestricted().
}