运行Java -jar somefile.jar时发生了什么(二)
2017-05-16 10:24
411 查看
(6)Java.c中的LoadMainClass
位置jdk/src/share/bin/java.c
该方法负责载入main函数所在的类。
该方法首先载入sun.launcher.LauncherHelper类,然后调用该类的checkAndLoadMain去找到main函数所在的类,相关代码例如以下。
(7)LauncherHelper.java中的checkAndLoadMain
位置:jdk/src/share/bin/classes/sun/launcher/LauncherHelper.java
Java代码比較直观。我就直接写凝视了
接下来给出了验证主类是否有效的代码。
二、总结
这两篇博客主要分析了运行java命令详细会发生一些什么事情,通过阅读代码能够了解到配置的环境变量怎样起作用。jvm何时初始化。以及主类载入及验证过程。
本片博客起码还有下面几点没有深入的分析到:
jvm怎样初始化。
env结构和vm结构的关系及实现。
scloader怎么作用。
LauncherHelper怎样载入。
这些问题也许会在后面的博客进行分析。
位置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怎样载入。
这些问题也许会在后面的博客进行分析。
相关文章推荐
- 执行Java -jar somefile.jar时发生了什么(一)
- 跑Java -jar somefile.jar时会发生什么(一个)
- 执行Java -jar somefile.jar时发生了什么(二)
- spark运行java-jar:Exception in thread "main" java.io.IOException: No FileSystem for scheme: hdfs
- maven将hadoop依赖打包成jar,运行jar后报错 java.io.IOException: No FileSystem for scheme
- jar包运行出现java.lang.SecurityException: Invalid signature file digest for Manifest main attributes的解决办法
- java打包 eclipse 打包 runnable jar file,及运行jar包操作
- cmd中java -jar *.jar 提示Unable to access jarfile *.jar或Windows不能用鼠标双击运行jar文件怎么办解决方案
- 在Mac下运行swt出错:java.lang.UnsatisfiedLinkError: no swt-carbon-3346 or swt-carbon in swt.library.path, java.library.path or the jar file
- Java中运行表达式return 1.0/0.0会发生什么?return 1/0会发生什么?
- java新手,什么情况下发生编译错误,什么情况下发生运行错误!
- Myeclipse中Struts2运行问题:Could not create JarEntryRevision for [jar:file:/E:/Java/Tomcat%206.0/webapps/Struts2.1/WEB-INF/lib/struts
- jar运行发生ClassNotFound的完整解决方案
- 什么是java平台及jar、jad及sis区别
- 第1章 Java基本概念及环境配置——FAQ1.17 怎样制作鼠标双击就可以运行的Jar文件?
- 详解jar命令打包生成双击即可运行的Java程序
- java 将应用程序打成可执行的JAR包,然后使用批处理方式运行
- 将java源码打包成可运行的jar的最简单的方法
- 在非web环境下,直接用java命令行运行程序时,对于通过getResources找不到jar包中的资源和目录的解决方法
- No configuration found. Configuring ehcache from ehcache-failsafe.xml found in the classpath: jar:file:/D:/package/java/hibernat