cc.shacocloud.mirage.loader.MirageClassLoader Maven / Gradle / Ivy
package cc.shacocloud.mirage.loader;
import cc.shacocloud.mirage.loader.jar.Handler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.Enumeration;
import java.util.function.Supplier;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
/**
* mirage 启动类加载器
*
* @author 思追(shaco)
* @date 2023/3/15
*/
public class MirageClassLoader extends URLClassLoader {
static {
// 注册为支持并行的
ClassLoader.registerAsParallelCapable();
}
private final boolean exploded;
private final cc.shacocloud.mirage.loader.jar.JarFile jarFile;
private final Object packageLock = new Object();
private volatile DefinePackageCallType definePackageCallType;
public MirageClassLoader(URL[] urls, ClassLoader parent) {
this(false, urls, parent);
}
public MirageClassLoader(boolean exploded, URL[] urls, ClassLoader parent) {
this(exploded, null, urls, parent);
}
public MirageClassLoader(boolean exploded, cc.shacocloud.mirage.loader.jar.JarFile jarFile, URL[] urls, ClassLoader parent) {
super(urls, parent);
this.exploded = exploded;
this.jarFile = jarFile;
}
@Override
public URL findResource(String name) {
if (this.exploded) {
return super.findResource(name);
}
Handler.setUseFastConnectionExceptions(true);
try {
return super.findResource(name);
} finally {
Handler.setUseFastConnectionExceptions(false);
}
}
@Override
public Enumeration findResources(String name) throws IOException {
if (this.exploded) {
return super.findResources(name);
}
Handler.setUseFastConnectionExceptions(true);
try {
return new UseFastConnectionExceptionsEnumeration(super.findResources(name));
} finally {
Handler.setUseFastConnectionExceptions(false);
}
}
@Override
protected Class> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (this.exploded) {
return super.loadClass(name, resolve);
}
Handler.setUseFastConnectionExceptions(true);
try {
try {
definePackageIfNecessary(name);
} catch (IllegalArgumentException ex) {
if (getPackage(name) == null) {
// 这不应该发生,因为 IllegalArgumentException 指示包已被定义,因此,getPackage(name) 不应返回空值
throw new AssertionError("包 " + name + " 已定义,但未能匹配");
}
}
return super.loadClass(name, resolve);
} finally {
Handler.setUseFastConnectionExceptions(false);
}
}
/**
* 在进行 {@code findClass} 调用之前定义包,这对于确保嵌套 JAR 的相应清单与包相关联是必需的。
*/
protected void definePackageIfNecessary(@NotNull String className) {
int lastDot = className.lastIndexOf('.');
if (lastDot >= 0) {
String packageName = className.substring(0, lastDot);
if (getPackage(packageName) == null) {
try {
definePackage(className, packageName);
} catch (IllegalArgumentException ex) {
if (getPackage(packageName) == null) {
// 这不应该发生,因为 IllegalArgumentException 指示包已被定义,因此,getPackage(name) 不应返回空值
throw new AssertionError("包 " + packageName + " 已定义,但未能匹配");
}
}
}
}
}
private void definePackage(String className, String packageName) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction
© 2015 - 2025 Weber Informatics LLC | Privacy Policy