Java virtual host loading process

xiaoxiao2021-04-04  285

Java virtual host loading process

Briefly, well-known java.exe is a Java class file executive, but actually Java.exe program is just an enclosure, which will load jvm.dll (under Windows, under the Windows platform, under Linux and Solaris In fact, it is: libjvm.so, this dynamic connection library is the actual operation of the Java virtual machine. Wonderful Java.exe programs find and load the JVM.dll dynamic library, and call it to perform the Class file execution process. Source code, "Javatm 2 SDK, Standard Edition, V1.4.2 Fcscommunity Source Release", can be downloaded from Sun official website, the source code of the main analysis is: J2SE / SRC / Share / Bin / Java.c J2SE / SRC / Windows / bin / java_md.c 'Java program' source code so-called 'Java program', including java.exe / javaac.exe / javadoc.exe in JDK, Java_args macro to control generation Code, if the macro is not defined, compiling file control generation java.exe otherwise compiling file control to generate other 'Java programs'. For example: J2se / Make / Java / Javac / Makefile (this is a Javac compilation file): $ (cd) ../.. @ @ release = $ (substlease) full_version = $ ( Full_Version) J2SE / Make / Sun / Javac / Javac / Makefile (Call by Makefile): Java_Args = "{/" - j-ms8m / ", / "com.sun.tools.javac.main/"} " The JavaC.exe program generated by the same Java.c code will directly call the Java class method: com.sun.tools.javac.main, which makes it like a direct running EXE file, not defined Java_args Java.exe programs will call the class methods in the passing parameters. From Java.c's main entry function, the main () function is the process of reassigning parameter pointers in the main () function. Then call the function: CreateExecutionenvironment, the function mainly looks for the Directory of the Java runtime environment, and the JVM.DLL of the virtual machine core dynamic connection library file path. According to the operating system, this function has different implementations, but the general processing logic is the same, we look at the process of the Windows platform (J2SE / SRC / Windows / Bin / Java_MD.c). The CreateExecutionenvironment function is mainly divided into three steps: a, look up the JRE path. B, load the virtual machine dynamic connection library (JVM.DLL) parameter specified in JVM.CFG. C, take the jvm.dll file path. Implementation: a, lookup JRE path is made in java_md.c: getJrepath is implemented.

This function first calls the getApplicationHome function, the GetApplicationHome function calls the WindowsAPI function getModuleFileName takes the absolute path of the Java.exe program, take my JDK installation path as an example: "D: /java/j2sdk1.4.2_04/bin/java.exe" Then, then remove the file name to take the absolute path to: "D: /java/j2sdk1.4.2_04/bin", will then remove the last level directory, now the absolute path is: "D: /java/j2sdk1.4.2_04". Then the getjrepath function continues to determine if the Java.dll file that has just been taken / bin / java.dll is existing, if there is, "D: /java/J2SDK1.4.2_04" is the JRE path, otherwise it is determined " D: /java/j2sdk1.4.2_04 "Path / JRE / BIN / JAVA.DLL file exists," D: /java/j2sdk1.4.2_04/jre "is the JRE path. If the above two cases do not exist, look up from the registry (see Functions getPublicjrehome). Function: GetPublicJREHome to find HKEY_LOCAL_MACHINE / Software / JavaSoft / Java Runtime Environment / CurrentVersion key "current JRE version," judgment "current JRE version" is the version number as 1.4, if it is then taken HKEY_LOCAL_MACHINE / Software / JavaSoft / Java Runtime Environment / "Current JRE Release Number" / JavaHome is located as the JRE path. The JRE path returned by my JDK is: "D: /java/j2sdk1.4.2_04/jre". B, loading the JVM.cfg virtual machine dynamic connection library profile is implemented in java.c: ReadkNownVMS implementation. The function first combines the absolute path of the JVM.cfg file, JRE path / lib / arch (CPU architecture) / jvm.cfgarch (CPU architecture) is judged by the getarch function in java_md.c, the Windows platform in this function Only two cases: Win64 'IA64', other situations are 'i386'. My I386 so JVM.CFG file absolute path is: "D: /java/j2sdk1.4.2_04/jre/lib/i386/jvm.cfg".

The document is as follows: # # @ (#) jvm.cfg 1.7 03/01/23 # # Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. # Sun proPrietary / confidential. Uses Subject to license terms. # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # List of jvms That Can Be Used as an option to java, javac, etc. # Order is important - first in this list is The default jvm. # Note That this Both this file and it wers format area unsupported and # WILL Go Away in . a future release # # You may also select a JVM in an arbitrary location with the # "-XXaltjvm = " option, but that too is unsupported # and may not be available in a future release # -client KNOWN. - Server knower -hotspot aliased_to -client -classic warn -native error -green error (if we are careful, we will find me in the JDK directory: "D: /java/j2sdk1.4.2_04/jre/bin/client" and ": /Java/j2sdk1.4.2_04/jre/bin/server" There are jvm.dll files in both directories. Java is managing these different versions of JVM.DLL through the JVM.cfg profile.) ReadkNownVMS The function reads the configuration content in this file into a global variable of the JVM configuration structure, first jump over Release (line starting with '#'), then read the JVM parameters specified by '-' starting, each behavior is a JVM message, the first part is the JVM virtual machine name, the second part is configurable parameters, such as line : "- Client KNown" "-client" is a virtual machine name, and "known" is the configuration type parameter, "known" indicates the jvm.dll of the virtual machine, and "LiaSed_to" is represented as another jvm.dll Alias, "WARN" indicates that the virtual machine's JVM.dll does not exist but runs with other existing JVM.dll replacements, and "error" also means that the jvm.dll of the type of virtual machine does not exist and does not Take the existing jvm.dll replacement and directly throw an error message. When running the Java program, the judgment using that virtual machine is a function in java.c: checkjvmType, this function checks if there is a parameter specified in the Java running parameter, then read from the READKNOWNVMS function, JVM.cfg data structure Go to look for, which specifies different JVM types (eventually resulting in different JVM.DLLs).

There are two ways to specify the JVM type, one specified according to the JVM name in the jvm.cfg file, the second method is to specify directly, the methods they perform are "Java -j ", "Java -xxaltjvm = " or "Java -J-XX4Avm = ". If it is the first parameter transmission method, the checkjvmtype function takes the JVM name behind the parameter '-j', and then finds the JVM name before you find the same name, the '-' before you find the JVM name directly. Value; and the second method, it will return directly "-xxaltjvm =" or "-j-xxaltjvm =", the JVM type name; if you do not specify any of the two methods in the two methods when running Java, CheckJVMTYPE The JVM name in the first configuration in the configuration file is taken, and the '-' of the previous name returns to this value. This return value of the HECKJVMTYPE function will match the JRE path into the absolute path of JVM.dll in the following functions. For example, if "Java-J-Client Test" is used when running the Java program, ReadkNVms will read the parameter "-client" and then find the jvm.cfg read in the parameter read in the JVM name "-client", if there is Then "-" before the JVM name is directly returned "Client"; if you use the following parameters while running the Java program: "Java -xxaltjvm = d: /java/j2sdk1.4.2_04/jre/bin/client test", ReadkNownVms will return directly to "D: /java/j2sdk1.4.2_04/jre/bin/client"; if you do not have the above parameters, as "Java Test", because the first JVM in the JVM.cfg configuration file is "-Client", so the function ReadkNownVMS will also remove "-" before the JVM name returns "Client". In fact, this three middle situation is used by "D: /java/j2sdk1.4.2_04/jre/bin/client/jvm.dll" this JVM dynamic connection library to process Test this Class, see the getjvmpath function below. C, take the jvm.dll file path is made in java_md.c: getjvmpath is implemented. From the above two steps we have obtained the JRE path and the JVM type string. GetJVMPath function determines whether the JVM type string returned by CheckJVMType contains '/' or '/' if included in the JVM type string / jvm.dll as a full path to JVM, otherwise JRE path / bin / jvm Type string / jvm.dll as a full path to JVM. Take a look at the example above, the first case "Java-J-Client Test" JVM.dll path is: JRE path / bin / jvm type string / jvm.dll Follow my JDK path to: "D: /java/j2sdk1.4.2_04/jre" "/bin" 10s "/client" "/jvm.dll ". The second case "java -xaltjvm = d: /java/j2sdk1.4.2_04/jre/bin/client test" path is: JVM type string / jvm.dll is: ": / java / j2sdk1.4.2_04 /JRE/bin/client" "/jvm.dll "The third case" java test "is:" D: /java/j2sdk1.4.2_04/jre " " / bin " " / client " " / JVM.dll "is the same as the situation.

So these three situations are called JVM dynamic connection library "D: /java/j2sdk1.4.2_04/jre/bin/client/jvm.dll" to process Test classes. Let's further verify: Open the CMD Console: Set Java Load Debug E: / Work / Java_RESEARCH> SET _JAVA_LAUNCHER_DEBUG = 1 A situation E: / WORK / JAVA_RESEARCH> Java -j-Client Test.scandirectory ----_ java_launcher_debug - - JRE PATH IS D: /JAVA/J2SDK1.4.2_04/JRE JVM.CFG [0] = -> - Client <- jvm.cfg [1] = -> - server <- jvm.cfg [2] = > -Hotspot <- jvm.cfg [3] = -> - Classic <- jvm.cfg [4] = -> - native <- jvm.cfg [5] = -> - Green <- 299 Micro Seconds to Parse JVM .cfg JVM path is D: /java/j2sdk1.4.2_04/jre/bin/client/jvm.dll 2897 micro seconds to LoadJavaVM JavaVM args: version 0x00010002, ignoreUnrecognized is JNI_FALSE, nOptions is 2 option [0] = '-Djava .class.path =. 'option [1] =' -Dsun.java.command = test.ScanDirectory '50001 micro seconds to InitializeJVM main-class is' test.ScanDirectory 'Apps' argc is 0 10208 micro seconds to load main class ---- Java_Launcher_Debug ---- Usage: Java Test.scandirectory Dir [Output File] Situation E: / WORK / JAVA_RESEA RCH> java -xxaltjvm = d: /java/j2sdk1.4.2_04/jre/bin/client test.scandirectory ---- Java_Launcher_Debug ---- JRE PATH IS D: /JAVA/J2SDK1.4.2_04/jre jvm.cfg [0] = -> - Client <- jvm.cfg [1] = -> - Server <- jvm.cfg [2] = -> - Hotspot <- jvm.cfg [3] = -> - Classic <- JVM .cfg [4] = -> - native <- jvm.cfg [5] = -> - Green <

- 386 micro seconds to parse jvm.cfg JVM path is D: /java/j2sdk1.4.2_04/jre/bin/client/jvm.dll 2795 micro seconds to LoadJavaVM JavaVM args: version 0x00010002, ignoreUnrecognized is JNI_FALSE, nOptions is 2 option [0] = '-djava.class.path =.' Option [1] = '-dsun.java.command = Test.scandirectory' 49978 Micro Seconds To Initializejvm main-class is' Test.scandirectory 'Apps' ARGC IS 0 9598 micro seconds to load main class ----_ JAVA_LAUNCHER_DEBUG ---- usage: java test.ScanDirectory DIR [output file] case of a three E: / work / java_research> java test.ScanDirectory ----_ JAVA_LAUNCHER_DEBUG ---- JRE Path is d: /java/j2sdk1.4.2_04/jre jvm.cfg [0] = -> - Client <- jvm.cfg [1] = -> - server <- jvm.cfg [2] = -> - Hotspot <- jvm.cfg [3] = -> - Classic <- jvm.cfg [4] = -> - native <- jvm.cfg [5] = -> - Green <- 381 micro seconds to parse jvm.cfg jvm Path is D: /java/j2sdk1.4.2_04/jre/bin/client/jvm.dll 3038 Micro Seconds to Loadjav aVM JavaVM args: version 0x00010002, ignoreUnrecognized is JNI_FALSE, nOptions is 2 option [0] = option [1] = '-Dsun.java.command = test.ScanDirectory' 50080 micro seconds to '-Djava.class.path =.' InitializeJVM main-class is' test.ScanDirectory 'Apps' argc is 0 10215 micro seconds to load main class ----_ JAVA_LAUNCHER_DEBUG ---- usage: java test.ScanDirectory DIR [output file] JVM three paths are: JVM path is d: /java/j2sdk1.4.2_04/jre/bin/client/jvm.dll Other cases E: / WORK / JAVA_RESECH>

Java -j-server test.scandirectory ----_ java_launcher_debug ---- JRE PATH IS D: /JAVA/J2SDK1.4.2_04/jre jvm.cfg [0] = -> - Client <- jvm.cfg [1] = -> - Server <- jvm.cfg [2] = -> - Hotspot <- jvm.cfg [3] = -> - Classic <- jvm.cfg [4] = -> - native <- jvm.cfg [ 5] = -> - Green <- 377 Micro Seconds to Parse Jvm.cfg JVM Path IS D: /JAVA/J2SDK1.4.2_04/jre/bin/server/jvm.dll 2985 Micro Seconds to LoadJavaVM JavaVM Args: Version 0x00010002, ignoreUnrecognized is JNI_FALSE, nOptions is 2 option [0] = '-Djava.class.path =.' option [1] = '-Dsun.java.command = test.ScanDirectory' 62382 micro seconds to InitializeJVM Main-Class is' test .ScanDirectory 'Apps' argc is 0 12413 micro seconds to load main class ----_ JAVA_LAUNCHER_DEBUG ---- usage: java test.ScanDirectory DIR [output file] E: / work / java_research> java -XXaltjvm = D: / java /J2SDK1.4.2_04/jre/bin/server test.scandirectory ----_ java_launcher_debug ---- JRE PATH IS D: / JAVA / J2SDK1.4.2_04 / jre jvm.cfg [0] = -> - Client <- jvm.cfg [1] = -> - server <- jvm.cfg [2] = -> - Hotspot <- jvm.cfg [3 ] = -> - Classic <- jvm.cfg [4] = -> - native <- jvm.cfg [5] = -> - Green <- 376 micro seconds to parse jvm.cfg JVM PATH IS D: / JAVA / j2sdk1.4.2_04 / jre / bin / server / jvm.dll 2937 micro seconds to LoadJavaVM JavaVM args: version 0x00010002, ignoreUnrecognized is JNI_FALSE, nOptions is 2 option [0] = '-Djava.class.path =.' option [1 ] = '-Dsun.java.command = Test.scandirectory'

62725 micro seconds to InitializeJVM Main-Class is' test.ScanDirectory 'Apps' argc is 0 8942 micro seconds to load main class ----_ JAVA_LAUNCHER_DEBUG ---- usage: java test.ScanDirectory DIR [output file] can be seen from the above Out, if we installed multiple JDK or JRE versions, use "java-xxaltjvm =" to specify the absolute path to other versions of JVM.dll, as for the operation, ready to be tested. Let's go back to the main function of java.c to see how the jvm.dll found on it loads the hook execution. This operation is roughly divided into three steps: a, load the JVM.dll dynamic connection library. B. Initialize JVM.DLL and hook to the JNIENV (JNI Call Interface) instance. C, call the JNIENV instance to load and process the Class class. Implementation: a, loading the JVM.dll dynamic connection library is implemented by the main function to call Java_MD.c. First, the main function of a local variable InvocationFunctions constructed structure, function pointer two InvocationFunctions structure: typedef struct {CreateJavaVM_t CreateJavaVM; GetDefaultJavaVMInitArgs_t GetDefaultJavaVMInitArgs;} InvocationFunctions; LoadJavaVM function first calls the windows API functions: LoadLibrary jvm.dll loaded dynamic link library, Then, the export function JNI_CREATEJAVAVM and JNI_GETDEFAULTJAVAVMINITARGS in JVM.dll are then connected to the CreateJavAVM and getDefaultjavavMinitargs function pointer variables of the InvocationFaultJavaVMinitargs function pointer variable. JVM.DLL load work declares completed. B, initialize JVM.dll and hook to the JNIENV (JNI Call Interface) instance is through Java.c: InitializeJVM is done. The MAIN method first defines a JNIENV structure, which defines a number of function pointer variables related to loading Class class files, lookup class methods, and call class methods in the JNIENV structure. InitializeJVM will call the CreateJavaVM method for the InvocationFunctions structure variable of JNI_CREATEJAVAVM above JVM.dll, that is, call JVM.dll, which returns an instance of the JNIENV structure to the Pointer of the JNienv structure in Main. After the Jnienv pointer in Main, you can start processing the Class files after the JNIENV instance is acquired. C, call the JNIENV instance to load and process the Class class. A) If it is a JAR package.

If it is executed, the main function calls the function in java.c: getMAINCLASSNAME, this function uses the JNIENV instance and calls Java class: java.util.jar.jarfile method getManifest () and from return from Manifest Take the value of GetAttributes ("main-class"), namely the file in the JAR package: MAIN-INF / MANIFEST.MF Specifies the main class of Main-Class as the main class of the run. Then the main function will call the LoadClass method in java.c to load the main class (FindClass using the JNIENV instance). B) If it is a Class method. The main function is directly called Java.c loadClass method to load the class. The main function calls the jnienv instance's getStaticMethodID method to find the "public static void main (string [] args) method in the loaded Class primary class, and determine if the method is a public method, then call the JAVA class. MAIN method. Summary can be seen from the above code analysis. A, why JDK and JRE do not necessarily copy to the hard disk directly to the hard drive, set the PATH environment variable. Because the preferred method of Java runs JRE path is directly determined by obtaining the Java.exe absolute path, you can also find the JRE path if the PATH environment variable is set by modifying the registry option.

The modification method is as follows: First we copied java.exe to any directory, I will copy it to E: / TEMP, run in CMD: Clear Path Environment Variables E: / Temp> SET PATH = E: / Temp> Java Error opening registry key 'Software / JavaSoft / Java Runtime Environment' Error: could not find java.dll Error:. could not find Java 2 Runtime Environment to import the following registry file (java.reg) Windows registry Editor Version 5.00 [HKEY_LOCAL_MACHINE / SOFTWARE / JavaSoft] [HKEY_LOCAL_MACHINE / SOFTWARE / JavaSoft / Java Runtime Environment] "CurrentVersion" = "1.4" [HKEY_LOCAL_MACHINE / SOFTWARE / JavaSoft / Java Runtime Environment / 1.4] "JavaHome" = "D: //java//j2sdk1.4.2_04/ / jre "Re-execution display is normal, as follows: E: / TEMP> Java usage: java [-Options] class [args ...] or java [-Options] -jar jarfile [args .. ............................... .. he default VM is client -cp -classpath A;. separated list of directories, JAR archives, and ZIP archives to search for Class Files. -d =

转载请注明原文地址:https://www.9cbs.com/read-131888.html

New Post(0)