The order in which the JVM loads the jar packages

Source: Internet
Author: User
Tags lmap

When you use-xx:+traceclasspaths or execute jinfo on a server, you get the jar packages Classpath contains, for example:

Java.class.path = local/aaa/lib/spring-data-redis-1.8.3.release.jar:/usr/local/aaa/lib/ spring-tx-4.3.8.release.jar:/usr/local/aaa/lib/spring-jdbc-4.3.7.release.jar:/usr/local/aaa/lib/ Classmate-1.3.1.jar:/usr/local/aaa/lib/javax.servlet-api-3.1.0.jar:/usr/local/aaa/lib/mongodb-driver-3.4.2.jar :/usr/local/aaa/lib/xml-apis-2.0.2.jar:/usr/local/aaa/lib/ufc-api-utils-2.0.0.jar:/usr/local/aaa/lib/ Log4j-over-slf4j-1.7.25.jar:/usr/local/aaa/lib/tomcat-embed-websocket-8.5.14.jar: ...

The order of these jars is different machine is always not the same, usually no problem, so also did not think carefully, the order of these jar package is not the same. At the end of the previous troubleshooting question, there is a question as to why some machines will load the correct class and some are wrong. Because this paragraph on the line of a project, gray beta stage, so dragged a few days, interspersed with a look at the load related to some of the hotspot code, has not seen before, on the side of the guessing side to see. Because it is interspersed to see, afraid today to see tomorrow forget, so the end of the blog Connection journal recorded the process I see.

In short, after some search code, finally found in Rt.jar Jarfile This class, code in the JDK Src.zip package. Tracked with the Https://github.com/saaavsaaa/warn-report/blob/master/src/main/java/report/btrace/JarBTrace.java script:

The output of the normal server script:

Abnormal script output on the server:

This problem occurs on multiple servers, so the collection of multiple output can confirm this rule, in fact, in the end of the connection in the code record can also be seen, if there are multiple classes with the same name will only load the first one. On a server that doesn't have problems, Commons-codec-1.10.jar is loaded before Http-1.1.0.jar, and the server on the wrong side is just the opposite.

The private ArrayList path in/usr/lib/jvm/java-8-oracle/jre/lib/rt.jar!/sun/misc/urlclasspath.class has the URL of the jar that is loaded. This class also has a map of the loader:arraylist<urlclasspath.loader> Loaders,jar path and jarloader for each jar: hashmap<string, Urlclasspath.loader> Lmap. Lmap constructs var1 and joins the map by using the private synchronized urlclasspath.loader getloader (int Loader) method to eject the jar from the stack URLs. There are two urlclassloader loaded with different Urlclasspath instances, one with only a few jars under Jre/lib, and one with all. This is not important, however, and these jars are all loaded from classpath. So I used jinfo on several servers to output the Java.class.path, and compared to find the normal server and server, the order of the two jars is really different. So I guess the problem is that the JVM is in front of the Java.class.path assignment, perhaps the OS or something.

So decided to look at the Java.class.path initialization, code in/home/aaa/github/hotspot/src/share/vm/runtime/arguments.cpp:_java_class_path = New Systemproperty ("Java.class.path", "", true). The structure of the Systemproperty in/HOME/AAA/GITHUB/HOTSPOT/SRC/SHARE/VM/RUNTIME/ARGUMENTS.HPP:

 // Constructor SystemProperty(const char* key, const char* value, bool writeable) {   if (key == NULL) {     _key = NULL;   } else {     _key = AllocateHeap(strlen(key)+1, mtInternal);     strcpy(_key, key);   }   if (value == NULL) {     _value = NULL;   } else {     _value = AllocateHeap(strlen(value)+1, mtInternal);     ba(_value, value);   }   _next = NULL;   _writeable = writeable; }};

The structure seemed to have nothing to do with it, and then back to CPP and looked carefully and found:

    Following is JVMTI agent writeable properties.    Properties values is set to NULL and they is    //Os specific they is initialized in Os::init_system_properties_va Lues ().         Set OS Specific System Properties values    os::init_system_properties_values ();

This method is defined in OS.HPP, but the implementation is different from the system, so not in the corresponding CPP, I am the Linux system, so I went to find the/home/aaa/github/hotspot/src/os/linux/vm/os_ Linux.cpp, but there's nothing I want. Only the directory file read for Endorsed,ext,bootclasspath was found in Arguments.cpp.

The output location of the-xx:+traceclasspaths parameter is then found: [classpath: ...] The call chain:

/home/aaa/Github/hotspot/src/share/vm/runtime/thread.cpp:// Parse argumentsjint parse_result = Arguments::parse(args);
     Parse java_tool_options environment variable (if present)     jint result = Parse_java_tool_options_environment_ Variable (&SCP, &scp_assembly_required);     if (Result! = JNI_OK) {       return result;     }     Parse Javavminitargs structure passed in     result = Parse_each_vm_init_arg (args, &SCP, &scp_assembly_ Required, flag::command_line);     if (Result! = JNI_OK) {       return result;     }     _java_options environment variable (if present) (mimics classic VM)     result = Parse_java_options_ Environment_variable (&SCP, &scp_assembly_required);      if (result! = JNI_OK) {       return result;     }    

Both parse_java_tool_options_environment_variable and parse_java_options_environment_variable have calls Parse_each_vm_init_arg , a _java_options will overwrite Java_tool_options's same key configuration.

Parse_each_vm_init_arg This method came in and saw such a little pit, but it doesn't matter ...

  if (!match_option (option, "-djava.class.path", &tail) &&        !match_option (option, "- Dsun.java.command ", &tail) &&        !match_option (option,"-dsun.java.launcher ", &tail)) {        //Add All JVMs options to the Jvm_args string. This string        //was used later to set the Java.vm.args PerfData string constant.        The-djava.class.path and The-dsun.java.command Options is        //omitted from Jvm_args string as each has their own PerfData        //String constant object.        Build_jvm_args (option->optionstring);    }

This is where the above sentence is printed:

     Jint Arguments::p arse_each_vm_init_arg     Arguments::fix_appclasspath ():       if (! Printsharedarchiveandexit) {         _java_class_path->value ());       } 

then [Bootstrap Loader class Path=/usr/lib/jvm/java-8-oracle/jre/lib/resources.jar:/usr/lib/jvm/java-8-oracle/jre/ lib/rt.jar:/usr/lib/jvm/java-8-oracle/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jsse.jar:/usr/ lib/jvm/java-8-oracle/jre/lib/jce.jar:/usr/lib/jvm/java-8-oracle/jre/lib/charsets.jar:/usr/lib/jvm/ Java-8-oracle/jre/lib/jfr.jar:/usr/lib/jvm/java-8-oracle/jre/classes] This sentence output:

    /home/aaa/github/hotspot/src/share/vm/runtime/init.cpp    jint init_globals ()    /home/aaa/github/hotspot/src /share/vm/classfile/classloader.cpp    void Classloader_init () {      classloader::initialize ();    }    void Classloader::initialize ()    void Classloader::setup_bootstrap_search_path ()

In general the code is in this section, you can see that the code does not change the loading order, and then the more important clue is the loading method with the Opendir and Readdir functions, with the assistance of iOS colleagues, finally determined that the problem is the jar loading order problem, This order is actually determined by the file system, and Linux internally uses the Inode to indicate the file.

So I wrote a simple C method to verify, print the inode number: HTTPS://GITHUB.COM/SAAAVSAAA/WARN-REPORT/BLOB/MASTER/SRC/MAIN/JAVA/REPORT/MAIN.C

  d_off:4066763678044974396 D_name:commons-codec-1.10.jar d_off:4317940688349827723 D_name:commons-lang-2.5.jar d_ off:4319988583919237504 D_name:jul-to-slf4j-1.7.25.jar d_off:4356646752930279233 D_name: Spring-aop-4.3.8.release.jar d_off:4579877846802590742 D_name:tomcat-embed-core-8.5.14.jar D_off : 4731608207059974753 d_name:groovy-2.4.3.jar d_off:4771541818858258978 D_name:jpush-client-3.2.9.jar D_off : 4817159055427520488 d_name:httpcore-4.3.jar d_off:5037058976412869958 D_name:rocketmq-common-3.2.6.jar D_off  : 5112026581585883935 D_name:xmlparserapis-2.6.2.jar d_off:5223887631628650300 D_name:commons-fileupload-1.2.2.jar d_off:5270962929984509613 D_name:logback-core-1.1.11.jar d_off:5295594039709144434 D_name:jackson-core-2.8.8.jar D  _off:5313324231349868064 d_name:.  d_off:5369671282559728007 D_name:spring-webmvc-4.3.8.release.jar d_off:5480616600783493234 D_name:xalan-2.6.0.jar d_off:5598132018198955916 D_name:unbescape-1.1.0.release.jar d_off:5620136379821311472 D_name:spring-boot-starter-aop-1.5.3.release.jar d_off:5639942392021544761 D_name:mybatis-3.4.4.jar d_ off:5688537857783605585 D_name:validation-api-1.1.0.final.jar d_off:5689351964973998306 D_name: Json-lib-2.4-jdk15.jar d_off:5708471019688158398 D_name:tagsoup-0.9.7.jar d_off:5716046632217600256 d_name: Xom-1.0b3.jar d_off:5736731302988875630 D_name:p2p-repository-1.0-snapshot.jar d_off:5770969695350360533 d_name: Ognl-3.0.8.jar d_off:5946256519116188501 D_name:jackson-annotations-2.8.0.jar d_off:6011005565981751131 d_name: Jxl-2.6.jar d_off:6121401373763401899 D_name:spring-data-mongodb-1.10.3.release.jar d_off:6155887434083949861 d_ Name:icu4j-2.6.1.jar d_off:6203694621577639938 D_name:jboss-logging-3.3.0.final.jar d_off:6241670413890043636 d_ Name:jaxme-api-0.3.jar d_off:6317802240634228683 D_name:thymeleaf-2.1.5.release.jar d_off:6362118033392674189 d_ Name:logback-classic-1.1.11.jar d_off:6391821784225315730 D_name:snakeyaml-1.17.jar d_off:6447926989912518869 D_name:javassist-3.16.1-ga.jar d_off:6586996539318953387 D_name:spring-boot-1.5.3.release.jar d_ off:6682174700565688505 D_name:mybatis-spring-1.3.1.jar d_off:6858079168157560275 D_name:http-1.1.0.jar

As you can see from the previous normal server, the order is the same as this. And the server that went wrong:

  d_off:7500897893766328572 D_name:http-1.1.0.jar  d_off:7630237192571233449 d_name:jaxen-1.1-beta-4.jar  d_ off:7846439931967980783 D_name:xom-1.0b3.jar  d_off:7986273690820996399 d_name:jxl-2.6.jar  D_off : 8013065173263952359 d_name:spring-boot-starter-thymeleaf-1.5.3.release.jar  d_off:8231450206996036007 d_name : Spring-context-support-4.3.8.release.jar  d_off:8471297127500795042 D_name:jpush-client-3.2.9.jar  D_off : 8635726305307688944 D_name:commons-codec-1.10.jar

The same can be compared with the error server above, and generally, modify the file name, and then change back, or from a new upload, this number is still this, so the problem of the server on the stable replication. Then, the question finally can be finished, the reason is clear, the mentality is the bottom. Whatever it is, I'll just change the name to Zzzhttp. Then the problem is solved in the case that two packages are present.

  d_off:8635726305307688944 D_name:commons-codec-1.10.jar  d_off:8710228832141418589 d_name: Xercesimpl-2.6.2.jar  d_off:8722513994996448409 D_name:android-json-0.0.20131108.vaadin1.jar  D_off : 8754081964290049159 d_name:ufc-api-utils-2.0.0.jar  d_off:8830796801498266528 d_name:httpcore-4.3.jar  d_ off:8854152647200610772 D_name:tomcat-jdbc-8.5.11.jar  d_off:8971846312288780129 d_name: Spring-tx-4.3.8.release.jar  d_off:8986236906371055996 D_name:bcprov-jdk15-1.45.jar  D_off : 8988385379950226997 d_name:mysql-connector-java-5.1.30.jar  d_off:8994464230154278010 d_name: P2p-common-1.0-snapshot.jar  d_off:9012703293696799571 D_name:mybatis-spring-boot-starter-1.3.0.jar  d_ off:9057592519440006836 D_name:zzzhttp-1.1.0.jar

Journal Record: https://saaavsaaa.github.io/aaa/Java_Class_Path.html

Public Number:

                    

The order in which the JVM loads the jar packages

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.