gembin

          OSGi, Eclipse Equinox, ECF, Virgo, Gemini, Apache Felix, Karaf, Aires, Camel, Eclipse RCP

          HBase, Hadoop, ZooKeeper, Cassandra

          Flex4, AS3, Swiz framework, GraniteDS, BlazeDS etc.

          There is nothing that software can't fix. Unfortunately, there is also nothing that software can't completely fuck up. That gap is called talent.

          About Me

           

          equinox環(huán)境下開發(fā)bundle不需要引入java.*包而需要引入javax.*包的的原因

          ClassLoader(類加載器)是Java提供的抽象類,它是負責加載類的對象。ClassLoader 做的工作就是在JVM 中將類裝入內存。 當 JVM 需要使用類時,它根據(jù)名稱向 ClassLoader 請求這個類,然后 ClassLoader 返回一個表示這個類的 Class 對象。

          一、前提知識 ClassLoader


          ClassLoader(類 加載器)是Java提供的抽象類,它是負責加載類的對象。ClassLoader 做的工作就是在JVM 中將類裝入內存。 當 JVM 需要使用類時,它根據(jù)名稱向 ClassLoader 請求這個類,然后 ClassLoader 返回一個表示這個類的 Class 對象。


          所有java.*包內的類都是由ClassLoader完成加載的,而且在執(zhí)行java命令的時候ClassLoaer就已經被裝入內存中。通常在開發(fā)過程中使用java.*包內的類的時候,不再需要import 這些類了。


          二、Bundle中的ClassLoader


          在equinox環(huán)境下,每一個bundle都有獨立的classLoader,對應的類名為BundleLoader。

          每個bundle的classLoader都有parent,這個parent(父classLoader)就是類的委派模型中的上一層的classLoader。對應的類名為ParentClassLoader,它是這樣定義的



          private static class ParentClassLoader extends ClassLoader {

           
          protected ParentClassLoader() {

            
          super(null);

           }

          }


          這是一個空的classloader,它直接繼承了java.lang.ClassLoader 。java包中的所有類都是由java.lang.ClassLoader載入的,根據(jù)類的委派模型可以知道,繼承了ClassLoader就可以直接獲得需要的java類。



                      if (name.startsWith(JAVA_PACKAGE))

                        
          // 1) if startsWith "java." delegate to parent and terminate search

                        
          // we want to throw ClassNotFoundExceptions if a java.* class cannot be loaded from the parent.

                          return parent.loadClass(name);


          上面代碼是bundle加載class的流程圖中的第一步,通過parentClassLoader獲得所需java.*包中的類,如下圖所示。



           這就是bundle中不需要引入java.*包的原因。


          三、如何知道java.*這些類已經被裝載了呢?


          1、寫一個類如下:



          public class  A

          {

              
          public static void main(String[] args) 

              {

                  System.out.println(
          "Hello World!");

              }

          }



          2、編譯



          javac A.java


          3、運行



          java -verbose A


          顯示的部分內容如下:



          [Loaded java.lang.Object from shared objects file]

          [Loaded java.io.Serializable from shared objects file]

          [Loaded java.lang.Comparable from shared objects file]

          [Loaded java.lang.CharSequence from shared objects file]

          [Loaded java.lang.String from shared objects file]

          [Loaded java.lang.reflect.GenericDeclaration from shared objects file]

          [Loaded java.lang.reflect.Type from shared objects file]

          [Loaded java.lang.reflect.AnnotatedElement from shared objects file]

          [Loaded java.lang.Class from shared objects file]

          [Loaded java.lang.Cloneable from shared objects file]

          [Loaded java.lang.ClassLoader from shared objects file]

          ... (后面還有很多,不一一列舉)


           


          四、為什么需要引入javax.*包


          下面的代碼是另一篇文章 equinox實現(xiàn)Class Loader機制的代碼解讀  提過的,bundle類載入的流程圖片段代碼。



            ...

            String pkgName 
          = getPackageName(name);

                  
          // follow the OSGi delegation model

                  if (checkParent && parent != null) ...{

                      
          if (name.startsWith(JAVA_PACKAGE))

                        
          // 1) if startsWith "java." delegate to parent and terminate search

                        
          // we want to throw ClassNotFoundExceptions if a java.* class cannot be loaded from the parent.

                          return parent.loadClass(name);

                      
          else if (isBootDelegationPackage(pkgName))

                          
          // 2) if part of the bootdelegation list then delegate to parent and continue of failure

                          try ...{

                              
          return parent.loadClass(name);

                          } 
          catch (ClassNotFoundException cnfe) ...{

                              
          // we want to continue

                          }

                  }

           ...


          從上面的代碼可以看出,如果不是第一種情況(包名不是以java.開始的)就使用第二個判斷條件。


          isBootDelegationPackage(pkgName)返回的是true(這個配置在以后再說),所以執(zhí)行的是


          parent.loadClass(name);


          這 行代碼和第一個條件的代碼是一樣的,即還是使用parentClassLoader去加載javax.*的包。由于ClassLoader只加載了 java.*的包,所以這里是不能得到javax.*包中的類的,會導致 ClassNotFoundException 的錯誤。從上面的代碼可以知道,代碼中對ClassNotFoundException 沒有處理,而是 繼續(xù)執(zhí)行了。分別從import package、required bundles、bundle內部classpath和dynamic import 獲取javax.*的包。


          通常情況下,這些javax.*的包作為required bundle提供,而且只需要提供一次,并避免在其他的bundle中再次/重復提供(export)。



                  PackageSource source = findImportedSource(pkgName);

                  if (source != null) {

                      
          // 3) found import source terminate search at the source

                      result = source.loadClass(name);

                      
          if (result != null)

                          
          return result;

                      
          throw new ClassNotFoundException(name);

                  }

                  
          // 4) search the required bundles

                  source = findRequiredSource(pkgName);

                  
          if (source != null)

                      
          // 4) attempt to load from source but continue on failure

                      result = source.loadClass(name);

                  
          // 5) search the local bundle

                  if (result == null)

                      result 
          = findLocalClass(name);

                  
          if (result != null)

                      
          return result;

                  
          // 6) attempt to find a dynamic import source; only do this if a required source was not found

                  if (source == null) {

                      source 
          = findDynamicSource(pkgName);


          這就是需要引入javax.*包的原因。

          posted on 2008-05-05 10:26 gembin 閱讀(985) 評論(0)  編輯  收藏 所屬分類: OSGi

          導航

          統(tǒng)計

          常用鏈接

          留言簿(6)

          隨筆分類(440)

          隨筆檔案(378)

          文章檔案(6)

          新聞檔案(1)

          相冊

          收藏夾(9)

          Adobe

          Android

          AS3

          Blog-Links

          Build

          Design Pattern

          Eclipse

          Favorite Links

          Flickr

          Game Dev

          HBase

          Identity Management

          IT resources

          JEE

          Language

          OpenID

          OSGi

          SOA

          Version Control

          最新隨筆

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          free counters
          主站蜘蛛池模板: 巧家县| 凤山市| 安平县| 曲沃县| 裕民县| 新宁县| 公主岭市| 桐庐县| 永平县| 鹿邑县| 衡东县| 锡林郭勒盟| 京山县| 九寨沟县| 斗六市| 平昌县| 石阡县| 泗洪县| 胶南市| 台中县| 梧州市| 恩施市| 鲁山县| 和政县| 宣恩县| 马边| 舒兰市| 蕉岭县| 竹北市| 周宁县| 万盛区| 清涧县| 北安市| 紫金县| 奉节县| 石阡县| 宝兴县| 鹤峰县| 宜阳县| 临朐县| 桐乡市|