• 运行Java -jar somefile.jar时发生了什么(二)



    (6)Java.c中的LoadMainClass

    位置jdk/src/share/bin/java.c

    该方法负责载入main函数所在的类。

    该方法首先载入sun.launcher.LauncherHelper类,然后调用该类的checkAndLoadMain去找到main函数所在的类,相关代码例如以下。

    jclass cls = GetLauncherHelperClass(env);//这个函数载入了sun.launcher.LauncherHelper类
        NULL_CHECK0(cls);
        if (JLI_IsTraceLauncher()) {
            start = CounterGet();
        }
        NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,//找到方法id
                    "checkAndLoadMain",
                    "(ZILjava/lang/String;)Ljava/lang/Class;"));
    
        str = NewPlatformString(env, name);
        result = (*env)->CallStaticObjectMethod(env, cls, mid, USE_STDERR, mode, str);//调用这个静态方法


    (7)LauncherHelper.java中的checkAndLoadMain

    位置:jdk/src/share/bin/classes/sun/launcher/LauncherHelper.java

    Java代码比較直观。我就直接写凝视了

    </pre><p><pre name="code" class="java"> public static Class<?

    > checkAndLoadMain(boolean printToStderr, int mode, String what) { initOutput(printToStderr); // mode决定是直接传入的主类还是jar文件。即区分java -jar xxx.jar 还是 java xxx.class String cn = null; switch (mode) { case LM_CLASS: cn = what; break; case LM_JAR: cn = getMainClassFromJar(what);//这个函数的原理是抽取jar中的mainfest文件得到其主类 break; default: // should never happen throw new InternalError("" + mode + ": Unknown launch mode"); } cn = cn.replace('/', '.'); Class<?> mainClass = null; try { mainClass = scloader.loadClass(cn);//使用scloader载入,怎样载入水比較深。这里就不展开说了。

    } catch (NoClassDefFoundError | ClassNotFoundException cnfe) { if (System.getProperty("os.name", "").contains("OS X") && Normalizer.isNormalized(cn, Normalizer.Form.NFD)) { try { // On Mac OS X since all names with diacretic symbols are given as decomposed it // is possible that main class name comes incorrectly from the command line // and we have to re-compose it mainClass = scloader.loadClass(Normalizer.normalize(cn, Normalizer.Form.NFC)); } catch (NoClassDefFoundError | ClassNotFoundException cnfe1) { abort(cnfe, "java.launcher.cls.error1", cn); } } else { abort(cnfe, "java.launcher.cls.error1", cn); } } // set to mainClass appClass = mainClass; /* * Check if FXHelper can launch it using the FX launcher. In an FX app, * the main class may or may not have a main method, so do this before * validating the main class. */ if (mainClass.equals(FXHelper.class) || FXHelper.doesExtendFXApplication(mainClass)) { // Will abort() if there are problems with the FX runtime FXHelper.setFXLaunchParameters(what, mode); return FXHelper.class; } validateMainClass(mainClass);//这里对主类有效性即可了验证,代码附在后面。 return mainClass; }



    
    接下来给出了验证主类是否有效的代码。
    

    static void validateMainClass(Class<?> mainClass) {
            Method mainMethod;
            try {
                mainMethod = mainClass.getMethod("main", String[].class);//看看是否存在例如以下签名的方法 main(String[] argvs)
            } catch (NoSuchMethodException nsme) {
                // invalid main or not FX application, abort with an error
                abort(null, "java.launcher.cls.error4", mainClass.getName(),
                      FXHelper.JAVAFX_APPLICATION_CLASS_NAME);
                return; // Avoid compiler issues
            }
    
    
            int mod = mainMethod.getModifiers();//取得限定符
            if (!Modifier.isStatic(mod)) {//假设不是static的则报错
                abort(null, "java.launcher.cls.error2", "static",
                      mainMethod.getDeclaringClass().getName());
            }
            if (mainMethod.getReturnType() != java.lang.Void.TYPE) {
                abort(null, "java.launcher.cls.error3",//假设不是void的也报错
                      mainMethod.getDeclaringClass().getName());
            }
        }


    二、总结


    这两篇博客主要分析了运行java命令详细会发生一些什么事情,通过阅读代码能够了解到配置的环境变量怎样起作用。jvm何时初始化。以及主类载入及验证过程。


    本片博客起码还有下面几点没有深入的分析到:

    jvm怎样初始化。

    env结构和vm结构的关系及实现。

    scloader怎么作用。

    LauncherHelper怎样载入。

    这些问题也许会在后面的博客进行分析。


  • 相关阅读:
    有用的sql语句积累
    spring boot sso 学习资源
    notepad++ 常用快捷键
    artTemplate的使用总结
    ajax完整请求
    03 Mybatis框架---学习笔记1--框架的概念及优势
    02 Struts2框架----学习笔记2(了解一下,已过时)
    IDEA 获取类的相对路径和绝对路径
    01 Struts2框架学习(了解一下,已过时)
    喜马拉雅 FM 已购付费音频下载
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6860084.html
Copyright © 2020-2023  润新知