少年阿賓

          那些青春的歲月

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks
          昨天,看一個build Standalone中databrusher的一個腳本,發現一個Java類似乎沒有在classpath中,好像也可一直運行了。很疑惑,問了對應的開發同學,然后自己好好看了下它的代碼,才知道了原理。
          命令是:$JAVA_HOME/bin/java $JAVA_OPTS com.alibaba.standalone.AppStartor com.alibaba.intl.standalone.databrusher.Startor "$main_class" "$signal_file" "$recivers"
          原理是:Java根據classpath找到,com.alibaba.standalone.AppStartor這個class,運行這個class,會啟動一個classloader來加載com.alibaba.intl.standalone.databrusher.Startor(在里面會指定到WORLDS-INF目錄下加載類),然后com.alibaba.intl.standalone.databrusher.Startor會啟動對應的"$main_class".
          然后,花了挺多時間好好看了一下Java的classloader,了解一下其中的原理和看了下代碼。下面也簡單總結一下吧。
          java虛擬機是由sun.misc.Launcher來初始化的,也就是java(或java.exe)這個程序來做的.虛擬機按以下順序搜索并裝載所有需要的類:
            1,引導類:組成java平臺的類,包含rt.jar和i18n.jar等基礎jar包中的類.
            2,擴展類:使用java擴展機制的類,都是位于擴展目錄($JAVA_HOME/jre/lib/ext)中的.jar檔案包.
            3,用戶類:開發者定義的類或者沒有使用java擴展機制的第三方產品.你必須在命令行中使用-classpath選項或者使用CLASSPATH環境變量來確定這些類的位,或者自己寫ClassLoader加載。
          Java的class loader的大致情況如下圖所示:
          http://renyongjie668.blog.163.com/prevPhDownload.do?host=renyongjie668&albumId=197449439&photoId=6568564371
          bootstrap classloader -->extension classloader-->system classloader
          虛擬機一啟動,會先做一些初始化的動作。一旦初始化動作完成之后,就會 產生第一個類別加載器,即所謂的Bootstrap Loader,Bootstrap Loader 是由C++ 所撰寫而成,這個Bootstrap Loader所做的初始工作中,除了也做一些基本的初始化動作之外,最重要的就是加載定義在sun.misc 命名空間底下的Launcher.java 之中的ExtClassLoader( 因為是inner class ,所以編譯之后會變成Launcher$ExtClassLoader.class) ,并設定其Parent 為null,代表其父加載器為Bootstrap Loader 。然后Bootstrap Loader ,再要求加載定義于sun.misc 命名空間底下的Launcher.java 之中的AppClassLoader( 因為是inner class,所以編譯之后會變成Launcher$AppClassLoader.class) ,并設定其Parent 為之前產生的ExtClassLoader 實例。
          a. Bootstrap ClassLoader/啟動類加載器
          主要負責java_home/jre/lib目錄下的核心 api 或 -Xbootclasspath 選項指定的jar包裝入工作.
          b. Extension ClassLoader/擴展類加載器
          主要負責java_home/jre/lib/ext目錄下的jar包或 -Djava.ext.dirs 指定目錄下的jar包裝入工作
          c. System ClassLoader/系統類加載器
          主要負責java -classpath/-Djava.class.path或$CLASSPATH變量所指的目錄下的類與jar包裝入工作.(這里需要說明的是,如果$CLASSPATH為空,jdk會默認將被運行的Java類的當前路徑作為一個默認的$CLASSPATH,一但設置了$CLASSPATH變量,則會到$CLASSPATH對應的路徑下去尋找相應的類,找不到就會報錯。這個結論,我已經經過測試,并且看了下類加載器中源代碼)
          d. User Custom ClassLoader/用戶自定義類加載類(java.lang.ClassLoader的子類)在程序運行期間, 通過java.lang.ClassLoader的子類動態加載class文件, 體現java動態實時類裝入特性.
          為了有更多的了解,寫了個簡單的Java程序對前面三種classloader能加載類的路徑及其parent類進行了測試。代碼如下:
          import java.net.URL;
          import java.net.URLClassLoader;
           /**
           * @className: IClassLoader
           * @description: 測試三種classloader加載類的路徑,及其parent
           * @author: 笑遍世界
           * @createTime: 2010-11-17 下午07:33:40
           */
          public class IClassLoader {
              public static void main(String[] args) {
          //        測試bootstrap classloader 的類加載路徑
                  URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs();
                  for (int i = 0; i < urls.length; i++) {
                    System.out.println(urls[i].toExternalForm());
                  }
                 
          //        測試extension classloader 的類加載路徑,先打印一個路徑,再打印出其parent,然后再打印出類加載路徑中的所有jar包
                  System.out.println("-------------------------------------");
                  System.out.println(System.getProperty("java.ext.dirs"));
                  ClassLoader extensionClassloader=ClassLoader.getSystemClassLoader().getParent();
                  System.out.println("the parent of extension classloader : "+extensionClassloader.getParent());
                  System.out.println("extension classloader can use thess jars:");
                  URL[] extURLs = ((URLClassLoader)ClassLoader.getSystemClassLoader().getParent()).getURLs();
                  for (int i = 0; i < extURLs.length; i++) {
                         System.out.println(extURLs[i]);
                  }       
                 
          //      測試system classloader 的類加載路徑,其實也就時classpath的路徑,并打印出它的parent
                  System.out.println("-------------------------------------");
                  System.out.println(System.getProperty("java.class.path"));
                  System.out.println(ClassLoader.getSystemResource(""));
                  ClassLoader systemClassloader=ClassLoader.getSystemClassLoader();
                  System.out.println("the parent of system classloader : "+systemClassloader.getParent());
              }
          }

          本機(linux+jdk1.5)運行結果如下:
          file:/usr/ali/java/jre/lib/rt.jar
          file:/usr/ali/java/jre/lib/i18n.jar
          file:/usr/ali/java/jre/lib/sunrsasign.jar
          file:/usr/ali/java/jre/lib/jsse.jar
          file:/usr/ali/java/jre/lib/jce.jar
          file:/usr/ali/java/jre/lib/charsets.jar
          file:/usr/ali/java/jre/classes
          -------------------------------------
          /usr/ali/java/jre/lib/ext
          the parent of extension classloader : null
          extension classloader can use thess jars:
          file:/usr/ali/java/jre/lib/ext/emma.jar
          file:/usr/ali/java/jre/lib/ext/localedata.jar
          file:/usr/ali/java/jre/lib/ext/dnsns.jar
          file:/usr/ali/java/jre/lib/ext/sunpkcs11.jar
          file:/usr/ali/java/jre/lib/ext/sunjce_provider.jar
          -------------------------------------
          .:/usr/ali/java/lib/dt.jar:/usr/ali/java/lib/tools.jar
          file:/home/master/workspace/2010_11/bin/
          the parent of system classloader :  sun.misc.Launcher$ExtClassLoader@1a5ab41
          //ps:當前路徑.即是/home/master/workspace/2010_11/bin/



          關于Java的classloader其原理還是需要好好理解才能清楚的,僅通過一天的了解,記錄為上面那么多吧。更多詳細信息,可以參考如下資料:
          http://snandy.javaeye.com/blog/307083
          http://haofenglemon.javaeye.com/blog/426382
          http://blog.csdn.net/zdwzzu2006/archive/2008/04/05/2253982.aspx
          http://wuquanyin1011.javaeye.com/blog/703842
          http://hi.baidu.com/yangzhibin_bai/blog/item/78846cce1cb86b0992457ead.html
          http://www.aygfsteel.com/clraychen/archive/2008/02/20/180868.html



          posted on 2013-09-07 15:43 abin 閱讀(857) 評論(0)  編輯  收藏 所屬分類: JVM
          主站蜘蛛池模板: 阳高县| 西盟| 深泽县| 西充县| 行唐县| 合山市| 灵川县| 新乐市| 靖江市| 伊宁市| 灵璧县| 都匀市| 峨边| 涿鹿县| 扬州市| 奉贤区| 安陆市| 泸溪县| 靖西县| 休宁县| 如皋市| 建昌县| 嘉兴市| 清水河县| 东台市| 涞水县| 满城县| 绿春县| 嘉兴市| 天水市| 泽库县| 新安县| 土默特左旗| 和林格尔县| 舞阳县| 肇源县| 屏东县| 永兴县| 元阳县| 崇信县| 甘南县|