In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
Today, I will talk to you about the implementation process of the Main method, which may not be well understood by many people. In order to make you understand better, the editor has summarized the following contents for you. I hope you can get something according to this article.
A simple Main method
Public class Mm {public static void main (String [] args) {Mm mm = new Mm (); System.out.println (mm.getClass (). GetClassLoader ());}} javac Mm.java java Mm is compiled and executed once
But if it is carried out as above, we can't debug it.
Therefore, java Mm commands should not be executed directly, but in gdb mode.
So we need to compile a version of openJDK first. The specific process of compiling OpenJdk code is Baidu. It is recommended to use the ubuntu system of Windows Store to compile.
The following is the OpenJdk source code, fork someone else's
Https://github.com/zscchaofan/openjdk-jdk8ugdb-q java Mm / / gdb set java command set args Mm / / set parameter name specific meaning do not understand Baidu search start / / start debugging below is a set of breakpoints are a try out of the gdb can directly specify the file and the number of lines breakpoint detailed commands can Baidu I am also Baidu do not summarize and do not often debug code If you don't refer to other people's tutorials, you have to take a few steps step by step, then use the gdb command to look at a few lines of code near the top and bottom of the current code, and then correspond to the source code. I, who don't understand the C++ language, can only take a step by step to see where the method name and intention is obvious, and then take a closer look at 3 breakpoint keep y 0x00007fffff1e7f4a in JavaMain. At / mnt/d/code/openjdk-jdk8u-master/jdk/src/share/bin/java.c:4784 breakpoint keep y 0x00007ffffc97da55 in Java_java_lang_ClassLoader_findBootstrapClass at / mnt/d/code/openjdk-jdk8u-master/jdk/src/share/native/java/lang/ClassLoader.c:2659 breakpoint keep y 0x00007fffff1e9c72 in GetLauncherHelperClass At / mnt/d/code/openjdk-jdk8u-master/jdk/src/share/bin/java.c:1250 breakpoint already hit 1 time14 breakpoint keep y 0x00007ffffc97da94 in Java_java_lang_ClassLoader_findBootstrapClass at / mnt/d/code/openjdk-jdk8u-master/jdk/src/share/native/java/lang/ClassLoader.c:27215 breakpoint keep y 0x00007ffffc97d3ea in Java_java_lang_ClassLoader_defineClass1 At / mnt/d/code/openjdk-jdk8u-master/jdk/src/share/native/java/lang/ClassLoader.c:107/mnt/d/code/openjdk-jdk8u-master is the path where I store the code, actually under d disk code. Add / mnt under ubuntu
After starting and debugging, gdb will stop automatically when it enters here. This is where it starts.
/ mnt/d/code/openjdk-jdk8u-master/jdk/src/share/bin/main.c
Main (int argc, char * * argv) {. . Omitting part of the code can't be understood anyway. . Return JLI_Launch (margc, margv, sizeof (const_jargs) / sizeof (char *), const_jargs, sizeof (const_appclasspath) / sizeof (char *), const_appclasspath, FULL_VERSION, DOT_VERSION, (const_progname! = NULL)? Const_progname: * margv, (const_launcher! = NULL)? Const_launcher: * margv, (const_jargs! = NULL)? JNI_TRUE: JNI_FALSE, const_cpwildcard, const_javaw, const_ergo_class);}
Continue to debug and find
/ mnt/d/code/openjdk-jdk8u-master/jdk/src/share/bin/java.c method, as follows
The FindBootStrapClass method looks for the class sun.launcher.LauncherHelper in jdk, which is the bridge between C++ and java code. When LauncherHelper is instantiated, it instantiates a system class loader AppClassLoader.
If (helperClass = = NULL) {NULL_CHECK0 (helperClass = FindBootStrapClass (env, "sun/launcher/LauncherHelper");}
Then look for the Main method of the execution class and execute it, that is, C++ calls the java method, sun.launcher.LauncherHelper#checkAndLoadMain
NULL_CHECK0 (mid = (* env)-> GetStaticMethodID (env, cls, "checkAndLoadMain", "(ZILjava/lang/String;) Ljava/lang/Class;")); because we are executing the java Mm command, we obviously find the main method from the Mm class. Others, such as the java-jar command, have other parsing methods to find the Main method.
The class Mm is found in the LauncherHelper.checkAndLoadMain method through Class.forName (), and the class loader of the virtual machine is definitely called according to the parent delegation mechanism.
At / mnt/d/code/openjdk-jdk8u-master/jdk/src/share/native/java/lang/ClassLoader.c:265 cls = JVM_FindClassFromBootLoader (env, clname); view parameter (gdb) p clname$53 = 0x7fffff7bf3c0 "Mm"
Virtual machine returned empty
At / mnt/d/code/openjdk-jdk8u-master/jdk/src/share/native/java/lang/ClassLoader.c:272 if (clname! = buf) {free (clname);} return cls;} View parameter (gdb) p cls$54 = (jclass) 0x0
So go back to the defineClass method of the parent class URLClassLoader in the AppClassLoader class loader in the java code to search for Mm.class, find it, and then call the virtual machine method to store the current class
Private native Class defineClass1 (String name, byte [] b, int off, int len, ProtectionDomain pd, String source) See here to understand why after the custom class loader loads the specified class, the new keyword will still be loaded with the system class loader when instantiating the object. The new keyword must be executed by the virtual machine. If the classes loaded by the class loader are not reported to the virtual machine, then the virtual machine is definitely not recognized.
After that, the virtual machine actually calls the Main method of Mm
/ mnt/d/code/openjdk-jdk8u-master/jdk/src/share/bin/java.c (* env)-> CallStaticVoidMethod (env, mainClass, mainID, mainArgs)
Although there is a call in the Main method
Mm mm = newMm (); method, but never go to the classloader again, because it has been loaded before
Summary
1. First of all, the execution of the main method requires an operation to start, a command like java Mm
two。 First of all, the operating system parses the java command to find something that belongs to jdk, and calls the startup function of jdk, just like the double-click operation of windows, double-click must be something the operating system did to open the software.
3. When the operating system invokes the command of the virtual machine, the virtual machine gets the parameters of the command, such as Mm, and then looks for the compiled file.
4. When the virtual machine finds the file, it calls the java code in jdk to find the class sun.launcher.LauncherHelper, which acts as a utility class and acts as a bridge between C++ and java code
5. Call the checkAndLoadMain method of the sun.launcher.LauncherHelper class, and use this method to find the Main method of the execution class Mm
6. Execute Main after loading
A question about the classloader
One question I've thought about before is how to use a custom class loader when instantiating the new keyword? Now it feels like it can't be implemented unless you replace jdk's classloader! / / Mainpublic class CustomerMain {public static void main (String [] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {CustomerClassLoader customerClassLoader = new CustomerClassLoader (); CustomerMain customerMain = (CustomerMain) (customerClassLoader.findClass ("CustomerMain") .newInstance ()) }} / / Custom class loader class CustomerClassLoader extends ClassLoader {@ Override protected Class findClass (String name) throws ClassNotFoundException {try {FileInputStream fileInputStream = new FileInputStream ("D:\\ code\\ zerolearnspring\\ target\\ classes\\ cn\\ learn\\ spring\\ zerolearnspring\\ controller\" + name + ".class") Byte [] bb = new byte [fileInputStream.available ()]; int read = fileInputStream.read (bb); return defineClass ("cn.doourbest.learn.spring.zerolearnspring.controller.CustomerMain", bb,0,read);} catch (FileNotFoundException e) {e.printStackTrace () } catch (IOException e) {e.printStackTrace ();} throw new ClassNotFoundException ("!!") }}-console error message Exception in thread "main" java.lang.ClassCastException: cn.doourbest.learn.spring.zerolearnspring.controller.CustomerMain cannot be cast to cn.doourbest.learn.spring.zerolearnspring.controller.CustomerMain at cn.doourbest.learn.spring.zerolearnspring.controller.CustomerMain.main (CustomerMain.java:18)
The java virtual machine book explains that the process of new objects must first check whether the parameters of this instruction can locate the symbolic reference of this class in the constant pool, and check whether the class represented by this symbolic reference has been loaded, parsed and initialized, and then implement the class loading process if it does not exist.
After reading the above, do you have any further understanding of the execution of the Main method? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.