JVM類載入源碼路徑

來源:互聯網
上載者:User

很早計劃寫篇研究JVM類載入源碼的,忙於項目一直沒時間深入研究,最近又要換工作,怕最近沒時間研究了。之前一些粗淺的研究,主要是defineClass()和loadClass()方法在JVM源碼中的幾個相關位置,作個簡單記錄。

 

1.defineClass

由位元組碼載入自訂類,最終歸結於java.lang.ClassLoader. defineClass0()這個native方法(關於java系統類別層面的類載入機制,參見之前的兩篇文章,本文只涉及JVM的c/c++層面源碼)。

 

該方法通過jni實現,對應的c代碼位於:

%openjdk-home%\jdk\src\share\native\java\lang\classload.c

實現該方法的幾層主要調用如下:

Java_java_lang_ClassLoader_defineClass1();

→JVM_DefineClassWithSource();

→jvm_define_class_common();

→SystemDictionary::resolve_from_stream();

 

%openjdk-home%\hotspot\src\share\vm\prims\jvm.cpp

 

最後一步用到的SystemDictionary這個類位於

%openjdk-home%\hotspot\src\share\vm\classfile\systemDictionary.cpp

 

SystemDictionary::resolve_from_stream()這個方法中,命名空間過濾部分源碼如下:

const char* pkg = "java/";

  if (!HAS_PENDING_EXCEPTION &&

      !class_loader.is_null() &&

      !parsed_name.is_null() &&

      !strncmp((const char*)parsed_name->bytes(), pkg, strlen(pkg))) {

    // It is illegal to define classes in the "java." package from

    // JVM_DefineClass or jni_DefineClass unless you're the bootclassloader

    ResourceMark rm(THREAD);

    char* name = parsed_name->as_C_string();

    char* index = strrchr(name, '/');

    *index = '\0'; // chop to just the package name

    while ((index = strchr(name, '/')) != NULL) {

      *index = '.'; // replace '/' with '.' in package name

    }

    const char* fmt = "Prohibited package name: %s";

    size_t len = strlen(fmt) + strlen(name);

    char* message = NEW_RESOURCE_ARRAY(char, len);

    jio_snprintf(message, len, fmt, name);

    Exceptions::_throw_msg(THREAD_AND_LOCATION,

      vmSymbols::java_lang_SecurityException(), message);

  }

 

高亮的幾行代碼可以看出:如類名以java.開頭,將拋出java.lang.SecurityException異常。之前。之前嘗試用自訂的方式載入系統類別時,發生異常,根源就在這裡。

 

理論上,刪除或修改這段代碼,就可以實現自訂系統類別載入。不過編譯JVM本身就是比較複雜的工作,至今尚未實現過~~~

 

2.loadClass

那麼以java.開頭java系統類別是如何?載入的?其流程與上面分析的基本類似。這裡不再詳細敘述,只給出幾個關鍵的方法:

 

(native方法) java.lang.Classload.findBootstrapClass()

→(classload.c) Java_java_lang_ClassLoader_findBootstrapClass

→(jvm.cpp) find_class_from_class_loader()

→(systemDictionary.cpp) resolve_instance_class_or_null()

→(java.lang.Classload.class)checkPackageAccess

→(java.lang.SecurityManager.class)checkPackageAccess

 

與之前有所不同的是安全檢查是通過JNI反調java方法實現的

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.