classload之java程序入口sun.misc.Launcher源码分析

本文深入分析Java程序的入口sun.misc.Launcher,探讨其初始化过程,包括BootClassPath、ExtClassLoader和AppClassLoader的详细运作。Launch类在初始化时设定ExtClassLoader的父类为BootstrapClassLoader,并将AppClassLoader设为全局变量和当前线程的contextClassLoader。此外,还讨论了bootClassPath、ExtClassLoader和AppClassLoader的角色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java程序的入口就是sun.misc.Launcher了,这个类里面又继承了ExtClassLoader和AppClassLoader和bootstrap的url路径。


1、Launch类初始化

private static Launcher launcher = new Launcher();
private static String bootClassPath =  System.getProperty("sun.boot.class.path");

    public static Launcher getLauncher() {
        return launcher;
    }

    private ClassLoader loader;

    public Launcher() {
        // Create the extension class loader
        ClassLoader extcl;
        try {
            extcl = ExtClassLoader.getExtClassLoader();
        } catch (IOException e) {
            throw new InternalError(
                "Could not create extension class loader");
        }

        // Now create the class loader to use to launch the application
        try {
            loader = AppClassLoader.getAppClassLoader(extcl);
        } catch (IOException e) {
            throw new InternalError(
                "Could not create application class loader");
        }

        // Also set the context class loader for the primordial thread.
        Thread.currentThread().setContextClassLoader(loader);

        // Finally, install a security manager if requested
        String s = System.getProperty("java.security.manager");
        ......
    }

    /*
     * Returns the class loader used to launch the main application.
     */
    public ClassLoader getClassLoader() {
        return loader;
    }

可以看到Launcher类初始化时,先初始化了个ExtClassLoader,然后又初始化了个AppClassLoader,然后把ExtClassLoader作为AppClassLoader的父loader。

ExtClassLoader没有指定父类,即表明,父类是BootstrapClassLoader。

把初始化的AppClassLoader 作为全局变量保存起来,并设置到当前线程contextClassLoader。

每个线程实例可以设置一个contextClassLoader


2、bootClassPath

Launcher 类有个全局的变量private static String  bootClassPath =        System.getProperty("sun.boot.class.path")  表示bootclassloader去哪里加载类和资源,看以下测试。
@Test
	public void test3(){
		System.out.println("bootstrap classload----------------------");
		final String s = System.getProperty("sun.boot.class.path");
    	System.out.println(s);
		final File[] path = (s == null) ? new File[0] : getClassPath(s);
		for(File f : path){
			System.out.println(f);
		}
		System.out.println();
		sun.misc.Launcher launcher = sun.misc.Launcher.getLauncher();
		System.out.println(launcher.getClass().getClassLoader());
		
	}

输出:
bootstrap classload----------------------
C:\Program Files\Java\jre1.8.0_77\lib\resources.jar;C:\Program Files\Java\jre1.8.0_77\lib\rt.jar;C:\Program Files\Java\jre1.8.0_77\lib\sunrsasign.jar;C:\Program Files\Java\jre1.8.0_77\lib\jsse.jar;C:\Program Files\Java\jre1.8.0_77\lib\jce.jar;C:\Program Files\Java\jre1.8.0_77\lib\charsets.jar;C:\Program Files\Java\jre1.8.0_77\lib\jfr.jar;C:\Program Files\Java\jre1.8.0_77\classes
C:\Program Files\Java\jre1.8.0_77\lib\resources.jar
C:\Program Files\Java\jre1.8.0_77\lib\rt.jar
C:\Program Files\Java\jre1.8.0_77\lib\sunrsasign.jar
C:\Program Files\Java\jre1.8.0_77\lib\jsse.jar
C:\Program Files\Java\jre1.8.0_77\lib\jce.jar
C:\Program Files\Java\jre1.8.0_77\lib\charsets.jar
C:\Program Files\Java\jre1.8.0_77\lib\jfr.jar
C:\Program Files\Java\jre1.8.0_77\classes

null


3、ExtClassLoader

extclassloader作为java中间的一个loader,实例化之后就放到classloader链里面了。
@Test
	public void test4(){
		System.out.println("ext classload----------------------");
		final String s = System.getProperty("java.ext.dirs");//对应路径
		System.out.println(s);
		
        File[] dirs;
        if (s != null) {
            StringTokenizer st =
                new StringTokenizer(s, File.pathSeparator);
            int count = st.countTokens();
            dirs = new File[count];
            for (int i = 0; i < count; i++) {
                dirs[i] = new File(st.nextToken());
            }
        } else {
            dirs = new File[0];
        }
		
        for(File f:dirs){
        	System.out.println(f.getAbsolutePath());
        }
	}

输出:
ext classload----------------------
C:\Program Files\Java\jre1.8.0_77\lib\ext;C:\Windows\Sun\Java\lib\ext
C:\Program Files\Java\jre1.8.0_77\lib\ext
C:\Windows\Sun\Java\lib\ext

extclassloader的url有点特殊,System.getProperty("java.ext.dirs")得到的是路径,jvm会把路径下面的所有文件都作为一个单独的url处理(一层路径)。

private static URL[] getExtURLs(File[] dirs) throws IOException {
            Vector<URL> urls = new Vector<URL>();
            for (int i = 0; i < dirs.length; i++) {
                String[] files = dirs[i].list();
                if (files != null) {
                    for (int j = 0; j < files.length; j++) {
                        if (!files[j].equals("meta-index")) {
                            File f = new File(dirs[i], files[j]);
                            urls.add(getFileURL(f));
                        }
                    }
                }
            }
            URL[] ua = new URL[urls.size()];
            urls.copyInto(ua);
            return ua;
        }

4、appclassloader

@Test
	public void test2(){
		System.out.println("app classload----------------------");
		final String s = System.getProperty("java.class.path");
		System.out.println(s);
        final File[] path = (s == null) ? new File[0] : getClassPath(s);
        for(File f : path){
        	System.out.println(f);
        }
	}

输出:
app classload----------------------
E:\java\my_workspace\myclassload\bin;E:\program\eclipse4.4-navi-32_2\eclipse4.4-navi-32\plugins\org.junit_4.11.0.v201303080030\junit.jar;E:\program\eclipse4.4-navi-32_2\eclipse4.4-navi-32\plugins\org.hamcrest.core_1.3.0.v201303031735.jar;/E:/program/eclipse4.4-navi-32_2/eclipse4.4-navi-32/configuration/org.eclipse.osgi/362/0/.cp/;/E:/program/eclipse4.4-navi-32_2/eclipse4.4-navi-32/configuration/org.eclipse.osgi/361/0/.cp/
E:\java\my_workspace\myclassload\bin
E:\program\eclipse4.4-navi-32_2\eclipse4.4-navi-32\plugins\org.junit_4.11.0.v201303080030\junit.jar
E:\program\eclipse4.4-navi-32_2\eclipse4.4-navi-32\plugins\org.hamcrest.core_1.3.0.v201303031735.jar
E:\program\eclipse4.4-navi-32_2\eclipse4.4-navi-32\configuration\org.eclipse.osgi\362\0\.cp
E:\program\eclipse4.4-navi-32_2\eclipse4.4-navi-32\configuration\org.eclipse.osgi\361\0\.cp






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值