Java Launcher代码分析(JDK src 下Launcher包)
2011-01-24 11:04
363 查看
Launcher是JRE中用于启动程序入口main()的类。分析这个类有助于理解JRE系统类的加载机制。
该类主要功能是:创建ExtClassLoader和AppClassLoader,还根据配置创建SercurityManager,设置进程上下文类加载器。
(一)Launcher初始化代码
private static Launcher launcher = new Launcher();
public static Launcher getLauncher() {
return launcher;
}
public Launcher() {
// 1. 创建扩展类加载器:ExtClassLoader
ClassLoader extcl;
try {
extcl = ExtClassLoader.getExtClassLoader();
} catch (IOException e) {
throw new InternalError(
“Could not create extension class loader”);
}
// 2. 创建用于启动应用程序的类加载器:AppClassLoader
try {
loader = AppClassLoader.getAppClassLoader(extcl);
} catch (IOException e) {
throw new InternalError(
“Could not create application class loader”);
}
// 3. 设置当前线程的上下文类加载器为前一步创建的AppClassLoader实例
Thread.currentThread().setContextClassLoader(loader);
//4. 根据需求创建安全管理器:SecurityManager实例
String s = System.getProperty(“java.security.manager”);
if (s != null) {
SecurityManager sm = null;
if (“”.equals(s) || “default”.equals(s)) {
sm = new java.lang.SecurityManager();
} else {
try {
sm = (SecurityManager)loader.loadClass(s).newInstance();
} catch (IllegalAccessException e) {
} catch (InstantiationException e) {
} catch (ClassNotFoundException e) {
} catch (ClassCastException e) {
}
}
if (sm != null) {
System.setSecurityManager(sm);
} else {
throw new InternalError(
“Could not create SecurityManager: ” + s);
}
}
}
创建Launcher几乎是用了一个Singleton模式,但令人疑惑的是其构造方法访问修饰符为public,这样就破坏了Singleton模式,可能是需要在必要的时候创建另一个Launcher实例。
(二)ExtClassLoader
关键代码如下:
String s = System.getProperty(“java.ext.dirs”);
File[] dirs = analyze(s);
URLClassLoader(dirs, null, factory);
因此,ExtClassLoader将加载变量“java.ext.dirs”的值指示的路径下的类,默认是jre安装目录/lib/ext,可以通过Djava.ext.dirs=…,来修改,这个指定目录是一些JDK或JRE的可选择功能扩展包。
(三)AppClassLoader
关键代码是:
final String s = System.getProperty(“java.class.path”);
final File[] path = (s == null) ? new File[0] : getClassPath(s);
return (AppClassLoader)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
URL[] urls =
(s == null) ? new URL[0] : pathToURLs(path);
return new AppClassLoader(urls, extcl);
}
});
可见,AppClassLoader取的是环境变量java.class.path中设定的路径作为类加载的搜索路径。
可以通过对该变量的设定来修改默认配置,实际上我们也常常这样做——虽然我们很少修改java.ext.dirs的值。
该类主要功能是:创建ExtClassLoader和AppClassLoader,还根据配置创建SercurityManager,设置进程上下文类加载器。
(一)Launcher初始化代码
private static Launcher launcher = new Launcher();
public static Launcher getLauncher() {
return launcher;
}
public Launcher() {
// 1. 创建扩展类加载器:ExtClassLoader
ClassLoader extcl;
try {
extcl = ExtClassLoader.getExtClassLoader();
} catch (IOException e) {
throw new InternalError(
“Could not create extension class loader”);
}
// 2. 创建用于启动应用程序的类加载器:AppClassLoader
try {
loader = AppClassLoader.getAppClassLoader(extcl);
} catch (IOException e) {
throw new InternalError(
“Could not create application class loader”);
}
// 3. 设置当前线程的上下文类加载器为前一步创建的AppClassLoader实例
Thread.currentThread().setContextClassLoader(loader);
//4. 根据需求创建安全管理器:SecurityManager实例
String s = System.getProperty(“java.security.manager”);
if (s != null) {
SecurityManager sm = null;
if (“”.equals(s) || “default”.equals(s)) {
sm = new java.lang.SecurityManager();
} else {
try {
sm = (SecurityManager)loader.loadClass(s).newInstance();
} catch (IllegalAccessException e) {
} catch (InstantiationException e) {
} catch (ClassNotFoundException e) {
} catch (ClassCastException e) {
}
}
if (sm != null) {
System.setSecurityManager(sm);
} else {
throw new InternalError(
“Could not create SecurityManager: ” + s);
}
}
}
创建Launcher几乎是用了一个Singleton模式,但令人疑惑的是其构造方法访问修饰符为public,这样就破坏了Singleton模式,可能是需要在必要的时候创建另一个Launcher实例。
(二)ExtClassLoader
关键代码如下:
String s = System.getProperty(“java.ext.dirs”);
File[] dirs = analyze(s);
URLClassLoader(dirs, null, factory);
因此,ExtClassLoader将加载变量“java.ext.dirs”的值指示的路径下的类,默认是jre安装目录/lib/ext,可以通过Djava.ext.dirs=…,来修改,这个指定目录是一些JDK或JRE的可选择功能扩展包。
(三)AppClassLoader
关键代码是:
final String s = System.getProperty(“java.class.path”);
final File[] path = (s == null) ? new File[0] : getClassPath(s);
return (AppClassLoader)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
URL[] urls =
(s == null) ? new URL[0] : pathToURLs(path);
return new AppClassLoader(urls, extcl);
}
});
可见,AppClassLoader取的是环境变量java.class.path中设定的路径作为类加载的搜索路径。
可以通过对该变量的设定来修改默认配置,实际上我们也常常这样做——虽然我们很少修改java.ext.dirs的值。
相关文章推荐
- 简单分析Launcher--/src/Workspace.Java
- jdk 源码分析(14)java ThreadLocal
- Java性能分析工具JDK VisualVM
- JDK源码分析之java.util.ArrayList
- jdk 源码分析(18)java io包分析
- java再复习——代码执行的大体流程与内存分析
- Java NIO原理图文分析及代码实现
- JDK源码分析Java.lang.Boolean的浅析——单例模式的应用(使我们更省内存)
- Java代码缺陷自动分析工具介绍
- Java NIO原理图文分析及代码实现
- Launcher.java中AppWidget添加过程分析
- JDK源码分析:java.lang.Boolean
- Java代码编写常见问题分析一
- 【转载】Java NIO原理图文分析及代码实现
- 深入XPath的详解以及Java示例代码分析
- Java NIO原理图文分析及代码实现
- Java线程池框架核心代码分析
- 利用jdk自带的运行监控工具JConsole观察分析Java程序的运行
- java内存分析、泄露、代码怎么更健壮
- 常用 Java 静态代码分析工具的分析与比较