《jdk8u源码分析》8.LoadJavaVM

src/windows/bin/java_md.c::LoadJavaVM

/*
 * Load a jvm from "jvmpath" and initialize the invocation functions.
 */
jboolean
LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
{
    HINSTANCE handle;

	//JVM path is C:\Tools\Java\open-jre1.8.0_202\bin\server\jvm.dll
    JLI_TraceLauncher("JVM path is %s\n", jvmpath);

    /*
     * The Microsoft C Runtime Library needs to be loaded first.  A copy is
     * assumed to be present in the "JRE path" directory.  If it is not found
     * there (or "JRE path" fails to resolve), skip the explicit load and let
     * nature take its course, which is likely to be a failure to execute.
     *
     */
    //加载%JRE_HOME%\\bin\\msvcr71.dll(_MSC_VER < 1400) | msvcr100.dll(_MSC_VER >= 1600)
    LoadMSVCRT();

    /* Load the Java VM DLL */
    //加载Microsoft C Runtime Library:
    //%JRE_HOME%\\bin\\${jvmtype}\\jvm.dll
    if ((handle = LoadLibrary(jvmpath)) == 0) {
    	//"Error: loading: %s"
        JLI_ReportErrorMessage(DLL_ERROR4, (char *)jvmpath);
        return JNI_FALSE;
    }

    /* Now get the function addresses */
    //获取接口地址并赋值到ifn中
    ifn->CreateJavaVM =
        (void *)GetProcAddress(handle, "JNI_CreateJavaVM");
    ifn->GetDefaultJavaVMInitArgs =
        (void *)GetProcAddress(handle, "JNI_GetDefaultJavaVMInitArgs");
    if (ifn->CreateJavaVM == 0 || ifn->GetDefaultJavaVMInitArgs == 0) {
        JLI_ReportErrorMessage(JNI_ERROR1, (char *)jvmpath);
        return JNI_FALSE;
    }

    return JNI_TRUE;
}

src/windows/bin/java_md.c::LoadMSVCRT

static jboolean
LoadMSVCRT()
{
    // Only do this once
    static int loaded = 0;
    char crtpath[MAXPATHLEN];

    if (!loaded) {
        /*
         * The Microsoft C Runtime Library needs to be loaded first.  A copy is
         * assumed to be present in the "JRE path" directory.  If it is not found
         * there (or "JRE path" fails to resolve), skip the explicit load and let
         * nature take its course, which is likely to be a failure to execute.
         * This is clearly completely specific to the exact compiler version
         * which isn't very nice, but its hardly the only place.
         * No attempt to look for compiler versions in between 2003 and 2010
         * as we aren't supporting building with those.
         */
//根据Microsoft C Runtime Library版本判断需要加载的dll文件
#ifdef _MSC_VER
#if _MSC_VER < 1400
#define CRT_DLL "msvcr71.dll"
#endif
#if _MSC_VER >= 1600
#define CRT_DLL "msvcr100.dll"
#endif
#ifdef CRT_DLL
		//获取JRE_HOME @see: 6.1.GetJREPath
		//MAXPATHLEN @see: 5.SelectVersion
        if (GetJREPath(crtpath, MAXPATHLEN)) {
        	//判断CRT_DLL路径是否超过系统最大路径长度
            if (JLI_StrLen(crtpath) + JLI_StrLen("\\bin\\") +
                    JLI_StrLen(CRT_DLL) >= MAXPATHLEN) {
                //"Error: Path length exceeds maximum length (PATH_MAX)"
                JLI_ReportErrorMessage(JRE_ERROR11);
                return JNI_FALSE;
            }
            (void)JLI_StrCat(crtpath, "\\bin\\" CRT_DLL);   /* Add crt dll */
            
            //CRT path is C:\Tools\Java\open-jre1.8.0_202\bin\msvcr100.dll
            JLI_TraceLauncher("CRT path is %s\n", crtpath);
            //判断CRT_DLL是否存在
            if (_access(crtpath, 0) == 0) {
            	//加载CRT_DLL
                if (LoadLibrary(crtpath) == 0) {
                	//"Error: loading: %s"
                    JLI_ReportErrorMessage(DLL_ERROR4, crtpath);
                    return JNI_FALSE;
                }
            }
        }
#endif /* CRT_DLL */
#endif /* _MSC_VER */
		//记录标志,防止重复加载
        loaded = 1;
    }
    return JNI_TRUE;
}

猜你喜欢

转载自blog.csdn.net/weixin_37477523/article/details/88363900