Launcher类源码分析
JDK开源:http://openjdk.java.net/
Launcher:
private static URLStreamHandlerFactory factory = new Launcher.Factory();
private static Launcher launcher = new Launcher();
private static String bootClassPath = System.getProperty("sun.boot.class.path");
private ClassLoader loader;
private static URLStreamHandler fileHandler;
public static Launcher getLauncher() {
return launcher;
}
public Launcher() {
//创建一个扩展类加载器
Launcher.ExtClassLoader var1;
try {
//这里是去创建扩展类加载器,返回扩展类加载器的实例
var1 = Launcher.ExtClassLoader.getExtClassLoader();
} catch (IOException var10) {
throw new InternalError("Could not create extension class loader", var10);
}
try {
//这里是去创建系统类加载器的实例,这里我们可以看到,getAppClassLoader(var1)中的参数var1是
//扩展类加载器get得到的结果,最终作为参数传递到getAppClassLoader中。
//并且赋给了loader,而loader又是Launcher类的一个私有成员变量。
//而且这句话也说明了, 扩展类加载器是系统类加载器的双亲!!!
this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);
} catch (IOException var9) {
throw new InternalError("Could not create application class loader", var9);
}
//Also set the conext class loader for the primordial thread
//还为原始线程设置conext(上下文)类加载器
Thread.currentThread().setContextClassLoader(this.loader);
//Finally,install a security manager if requested
//最终,如果需要,请安装安全管理器
String var2 = System.getProperty("java.security.manager");
if (var2 != null) {
SecurityManager var3 = null;
if (!"".equals(var2) && !"default".equals(var2)) {
try {
var3 = (SecurityManager)this.loader.loadClass(var2).newInstance();
} catch (IllegalAccessException var5) {
;
} catch (InstantiationException var6) {
;
} catch (ClassNotFoundException var7) {
;
} catch (ClassCastException var8) {
;
}
} else {
var3 = new SecurityManager();
}
if (var3 == null) {
throw new InternalError("Could not create SecurityManager: " + var2);
}
System.setSecurityManager(var3);
}
}
//调用这个方法就是返回loader(App),而 ExtClassLoader会通过getParent得到!
public ClassLoader getClassLoader() {
return this.loader;
}
ExtClassLoader:
//这里ExtClassLoader继承了URLClassLoader,URLClassLoader又继承了SecureClassLoader,
//SecureClassLoader又继承了ClassLoader
static class ExtClassLoader extends URLClassLoader, {
/*
create an ExClassLoader. The ExtClassLoader is created within a context that
limits which files it can read
创建一扩展类加载器,ExtClassLoader是在以下上下文中创建的限制它可以读取哪些文件
*/
public static Launcher.ExtClassLoader getExtClassLoader() throws IOException {
final File[] var0 = getExtDirs(); //就是返回扩展类加载器所加载的那几个目录路径
try {
//AccessController.doPrivilege主要是做一个权限的校验
return (Launcher.ExtClassLoader)AccessController.doPrivileged(new PrivilegedExceptionAction<Launcher.ExtClassLoader>() {
public Launcher.ExtClassLoader run() throws IOException {
int var1 = var0.length;
for(int var2 = 0; var2 < var1; ++var2) {
MetaIndex.registerDirectory(var0[var2]);
}
//最终返回一个ExtClassLoader,谁调用了,返回给谁!其实就是Launcher里面的
//var1 = Launcher.ExtClassLoader.getExtClassLoader();
return new Launcher.ExtClassLoader(var0);
}
});
} catch (PrivilegedActionException var2) {
throw (IOException)var2.getException();
}
}
void addExtURL(URL var1) {
super.addURL(var1);
}
public ExtClassLoader(File[] var1) throws IOException {
super(getExtURLs(var1), (ClassLoader)null, Launcher.factory);
SharedSecrets.getJavaNetAccess().getURLClassPath(this).initLookupCache(this);
}
//就是返回扩展类加载器所加载的那几个目录路径
private static File[] getExtDirs() {
//这个其实就是得到扩展类加载器所加载的那几个特定的目录路径
String var0 = System.getProperty("java.ext.dirs");
File[] var1;
if (var0 != null) {
//这里对多个路径进行分割
StringTokenizer var2 = new StringTokenizer(var0, File.pathSeparator);
int var3 = var2.countTokens(); //得到数目(几个路径)
var1 = new File[var3]; //最终放在var1这个数组中
for(int var4 = 0; var4 < var3; ++var4) {
var1[var4] = new File(var2.nextToken());
}
} else { //如果为空,就新new一个,返回回去
var1 = new File[0];
}
return var1;
}
private static URL[] getExtURLs(File[] var0) throws IOException {
Vector var1 = new Vector();
for(int var2 = 0; var2 < var0.length; ++var2) {
String[] var3 = var0[var2].list();
if (var3 != null) {
for(int var4 = 0; var4 < var3.length; ++var4) {
if (!var3[var4].equals("meta-index")) {
File var5 = new File(var0[var2], var3[var4]);
var1.add(Launcher.getFileURL(var5));
}
}
}
}
URL[] var6 = new URL[var1.size()];
var1.copyInto(var6);
return var6;
}
public String findLibrary(String var1) {
var1 = System.mapLibraryName(var1);
URL[] var2 = super.getURLs();
File var3 = null;
for(int var4 = 0; var4 < var2.length; ++var4) {
URI var5;
try {
var5 = var2[var4].toURI();
} catch (URISyntaxException var9) {
continue;
}
File var6 = (new File(var5)).getParentFile();
if (var6 != null && !var6.equals(var3)) {
String var7 = VM.getSavedProperty("os.arch");
File var8;
if (var7 != null) {
var8 = new File(new File(var6, var7), var1);
if (var8.exists()) {
return var8.getAbsolutePath();
}
}
var8 = new File(var6, var1);
if (var8.exists()) {
return var8.getAbsolutePath();
}
}
var3 = var6;
}
return null;
}
private static AccessControlContext getContext(File[] var0) throws IOException {
PathPermissions var1 = new PathPermissions(var0);
ProtectionDomain var2 = new ProtectionDomain(new CodeSource(var1.getCodeBase(), (Certificate[])null), var1);
AccessControlContext var3 = new AccessControlContext(new ProtectionDomain[]{var2});
return var3;
}
static {
ClassLoader.registerAsParallelCapable();
}
}
AppClassLoader:
//The class loader used for loading from java.class.path. runs in a restricted security
//context
//用于从java.class.path加载的类加载器。在受限制的安全上下文中运行
static class AppClassLoader extends URLClassLoader {
final URLClassPath ucp = SharedSecrets.getJavaNetAccess().getURLClassPath(this);
public static ClassLoader getAppClassLoader(final ClassLoader var0) throws IOException {
//和extClassLoader差不多,这里是获取系统类加载器所加载多个目录
final String var1 = System.getProperty("java.class.path");
final File[] var2 = var1 == null ? new File[0] : Launcher.getClassPath(var1);
return (ClassLoader)AccessController.doPrivileged(new PrivilegedAction<Launcher.AppClassLoader>() {
public Launcher.AppClassLoader run() {
URL[] var1x = var1 == null ? new URL[0] : Launcher.pathToURLs(var2);
//这里调用下面的AppClassLoader var0是扩展类加载器!
return new Launcher.AppClassLoader(var1x, var0);
}
});
}
//这里的var2参数,就是扩展类加载器,
AppClassLoader(URL[] var1, ClassLoader var2) {
super(var1, var2, Launcher.factory);
this.ucp.initLookupCache(this);
}
public Class<?> loadClass(String var1, boolean var2) throws ClassNotFoundException {
int var3 = var1.lastIndexOf(46);
if (var3 != -1) {
SecurityManager var4 = System.getSecurityManager();
if (var4 != null) {
var4.checkPackageAccess(var1.substring(0, var3));
}
}
if (this.ucp.knownToNotExist(var1)) {
Class var5 = this.findLoadedClass(var1);
if (var5 != null) {
if (var2) {
this.resolveClass(var5);
}
return var5;
} else {
throw new ClassNotFoundException(var1);
}
} else {
return super.loadClass(var1, var2);
}
}
protected PermissionCollection getPermissions(CodeSource var1) {
PermissionCollection var2 = super.getPermissions(var1);
var2.add(new RuntimePermission("exitVM"));
return var2;
}
private void appendToClassPathForInstrumentation(String var1) {
assert Thread.holdsLock(this);
super.addURL(Launcher.getFileURL(new File(var1)));
}
private static AccessControlContext getContext(File[] var0) throws MalformedURLException {
PathPermissions var1 = new PathPermissions(var0);
ProtectionDomain var2 = new ProtectionDomain(new CodeSource(var1.getCodeBase(), (Certificate[])null), var1);
AccessControlContext var3 = new AccessControlContext(new ProtectionDomain[]{var2});
return var3;
}
//这里是将其注册为可以并行加载的!
static {
ClassLoader.registerAsParallelCapable();
}
}
ClassLoader中初始化系统类加载器:
private static synchronized void initSystemClassLoader() {
if (!sclSet) {
if (scl != null)
throw new IllegalStateException("recursive invocation");
//得到创建的类加载器实例(其实系统类加载器,是否是扩展类加载器可以通过getParent去判别,即使用:
//new SystemClassLoaderAction(scl)去判断)
sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
if (l != null) {
Throwable oops = null;
scl = l.getClassLoader(); //得到系统类加载器
try {
scl = AccessController.doPrivileged(
//就是为了处理是:scl最终返回的是用户自定义系统类加载器还是默认的AppClassLoader
new SystemClassLoaderAction(scl));
} catch (PrivilegedActionException pae) {
oops = pae.getCause();
if (oops instanceof InvocationTargetException) {
oops = oops.getCause();
}
}
//异常处理
if (oops != null) {
if (oops instanceof Error) {
throw (Error) oops;
} else {
// wrap the exception
throw new Error(oops);
}
}
}
sclSet = true;
}
}
class SystemClassLoaderAction
implements PrivilegedExceptionAction<ClassLoader> {
private ClassLoader parent;
//上面调用这个实例时,将scl(系统类加载器传过来)
SystemClassLoaderAction(ClassLoader parent) {
this.parent = parent;
}
/**
★★★比较重要要的一段!★★★
*/
public ClassLoader run() throws Exception {
//自定义系统类加载器的系统属性
String cls = System.getProperty("java.system.class.loader");
//如果为null,说明我们没有设置前面这一句属性,
//说明系统类加载器就是默认的AppClassLoader
if (cls == null) {
return parent;
}
Constructor<?> ctor = Class.forName(cls, true, parent)
.getDeclaredConstructor(new Class<?>[] { ClassLoader.class });
ClassLoader sys = (ClassLoader) ctor.newInstance(
//这句代码也就说明为什么自定义系统类加载器的父亲是AppClassLoader
new Object[] { parent });
//sys 也就是用户自定义的系统类加载器,将其放进上下文类加载器
Thread.currentThread().setContextClassLoader(sys);
return sys;
}
}