程序人生

          在Java中摸爬滾打的日子

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            6 Posts :: 1 Stories :: 19 Comments :: 0 Trackbacks

          提供支撐的Bundles

          --- 瀟湘振宇 2010-06-26  

          上一篇中,我們已經為這基于OSGiWeb應用搭建了項目框架,但其中涉及到有幾個支撐OSGi環境下的SSH框架的Bundles的改造或提供未曾給大家詳細介紹。本篇內容就是為詳細介紹這幾個Bundles的作用及創建的過程。


          CGLIB的改造

          Cglib的改造曾在系列一中有提到,為了解決Hibernate在調用CGLIB來創建代理對象時找不到HibernateProxy對象的問題。改造也相當的簡單,只需要將AbstractClassGenerator類中的getClassLoader方法中的ClassLoad改為當前類所在的ClassLoad即可,如下所示:

          public ClassLoader getClassLoader() {

                  ClassLoader t = classLoader;

                  /**

                   * FIXME 更改classLoad的加載順序 

               *  if (t == null) {

               *      t = getDefaultClassLoader();

               *  }

               *  if (t == null) {

               *      t = getClass().getClassLoader();

               *  }

                   */

                  if (t == null) {

                      t = getClass().getClassLoader();

                  }

                  if (t == null) {

                      t = getDefaultClassLoader();

                  }

                  if (t == null) {

                      t = Thread.currentThread().getContextClassLoader();

                  }

                  if (t == null) {

                      throw new IllegalStateException("Cannot determine classloader");

                  }

                  return t;

              }

          以上是改造的內容,而我們在項目中應用的時候需要的是一個OSGiBundle,因此我們可以通過Pax-construct來創建這個Bundle

          大致過程是:首先在org.ideawork.osgi工程下面新建名為warpper的模塊,再到warpper目錄下面新建cglibbundle工程,并將其導入到IDE環境中。然后從官方網站下載cglib的源碼,將源碼添加到相應的工程,再對需要修改的地方修改之。

          具體步驟如下:

          1. 新建warpper的模塊

          通過Pax-Construct的命令來新建此warpper模塊,如下:

          >cd osgiapp

          >pax-create-module -g org.ideawork.osgiapp -a osgiapp-warpper -v 1.0.0

          其中osgiapp為當前這應用的根目錄,cd osgiapp為進入到根目錄下,而下面的命令則是創建module工程,這在上篇已經介紹過。

          2. 新建cglibbundle

          Cglibbundle工程的創建跟上篇中其他bundle的創建類似,命令如下:

          >cd osgiapp-warpper

          >pax-create-bundle -p org.ideawork.osgiapp.warpper.cglib -n osgiapp-warpper-cglib -g org.ideawork.osgiapp.warpper -v 2.1.3-001

                   這里之所以要指定版本號為2.1.3-001是因為我們改造的是2.1.3版的cglib,而后面的001代表的是我們自己的warpper工程的小版本號,如果以后有對此cglib bundle升級,但cglib的版本還是2.1.3,那時候我們就升級001這個版本號。

          3. 導入IDEEclipse

          導入方式如上篇所述,導入后的視圖如下:


          4. 添加cglib的源碼

          我們將從官方網站下載的cglib的源碼添加到cglib bundle下的src/main/java目錄下,并將新建此bundle工程時默認生成的org.ideawork.osgiapp.warpper.cglib的包刪除掉。刷新當前項目,此時會出現很多的紅叉叉,這是因為缺少相關的依賴包所致。因此我們需要在此bundle工程下的pom.xml文件中添加如下依賴信息:

          <dependencies>

          <dependency>

          <groupId>org.objectweb.asm</groupId>

          <artifactId>com.springsource.org.objectweb.asm</artifactId>

          <version>1.5.3</version>

          <scope>compile</scope>

          <optional>true</optional>

          </dependency>

          <dependency>

          <groupId>org.objectweb.asm</groupId>

          <artifactId>

          com.springsource.org.objectweb.asm.attrs

          </artifactId>

          <version>1.5.3</version>

          <scope>compile</scope>

          <optional>true</optional>

          </dependency>

          <dependency>

          <groupId>org.objectweb.asm</groupId>

          <artifactId>com.springsource.org.objectweb.asm.util</artifactId>

          <version>2.2.0</version>

          <scope>compile</scope>

          <optional>true</optional>

          </dependency>

          <dependency>

          <groupId>org.codehaus.aspectwerkz</groupId>

          <artifactId>com.springsource.org.codehaus.aspectwerkz.hook</artifactId>

          <version>1.0.0</version>

          <scope>compile</scope>

          <optional>true</optional>

          </dependency>

          <dependency>

          <groupId>org.apache.ant</groupId>

          <artifactId>com.springsource.org.apache.tools.ant</artifactId>

          <version>1.7.0</version>

          <scope>compile</scope>

          <optional>true</optional>

          </dependency>

          </dependencies>

          5. 修改ClassLoad加載順序

          修改AbstractClassGenerator類中的getClassLoader方法中的ClassLoad加載順序已經在上面描述過,大家按上面的修改即可。

          6. 完善MANIFEST.MF文件中的元數據信息

          這里關于MANIFEST.MF文件中的一些元數據,我們不想讓bnd為我們來生成,因為通過bnd工具生成的元數據,有時候生成的元數據過于龐大。因此我們在osgi.bnd文件中添加相關的元數據信息,并刪除新建項目時默認生成的Bundle-Activator元素,需要添加的內容如下:

          Export-Package = net.sf.cglib.asm;version="2.1.3","

           net.sf.cglib.asm.attrs;version="2.1.3";uses:="net.sf.cglib.asm","

           net.sf.cglib.beans;version="2.1.3";uses:="net.sf.cglib.asm,net.sf.cglib.core","

           net.sf.cglib.core;version="2.1.3";uses:="net.sf.cglib.asm","

           net.sf.cglib.proxy;version="2.1.3";uses:="net.sf.cglib.asm,net.sf.cglib.core,net.sf.cglib.reflect","

           net.sf.cglib.reflect;version="2.1.3";uses:="net.sf.cglib.asm,net.sf.cglib.core","

           net.sf.cglib.transform;version="2.1.3";uses:="net.sf.cglib.asm,net.sf.cglib.core,org.apache.tools.ant,org.apache.tools.ant.types","

           net.sf.cglib.transform.hook;version="2.1.3";uses:="net.sf.cglib.asm,net.sf.cglib.transform","

           net.sf.cglib.transform.impl;version="2.1.3";uses:="net.sf.cglib.asm,net.sf.cglib.core","

           net.sf.cglib.util;version="2.1.3";uses:="net.sf.cglib.asm,net.sf.cglib.core"

          Bundle-ClassPath = .

          Bundle-Version = 2.1.3

          JarJarStringTransformer = com.tonicsystems.jarjar.GeneratedStringTransformer

          Bundle-Name = CGLIB Code Generation Library

          Import-Package = org.apache.tools.ant;version="[1.7.0, 2.0.0)";resolution:=optional,"

           org.apache.tools.ant.types;version="[1.7.0, 2.0.0)";resolution:=optional,"

           org.codehaus.aspectwerkz.hook;version="[0.8.1, 0.9.0)";resolution:=optional,"

           org.objectweb.asm;version="[1.5.3, 2.0.0)";resolution:=optional,"

           org.objectweb.asm.attrs;version="[1.5.3, 2.0.0)";resolution:=optional

          DynamicImport-Package = *

          7. 編譯打包

          編譯打包的工作我們是交給Maven來幫我們做,但我們需要修改cglib bundle工程下的pom.xml文件中的properties元素的相關屬性內容做。需要將<bundle.namespace>org.ideawork.osgiapp.warpper.cglib</bundle.namespace>修改成<bundle.namespace>net.sf.cglib</bundle.namespace>,這樣修改的目的是因為在利用Maven編譯打包的時候,bnd插件會根據bundle工程的namespace的定義來導出相關的包,如果項目中的classis文件不在其namespace范圍內,打包時被會被忽略掉。

          修改完pom.xml文件后,在命令行窗口下進入到cglib bundle工程的目錄下,運行mvn -e clean install命令就可以將cglib bundle安裝到本地Maven倉庫。到這里cglib的改造完成。


          封裝Mysql Connector

          因為數據庫用的是Mysql,數據庫連接池使用的是C3p0,因為C3p0在創建數據庫連接池的時候需要使用到指定的驅動包,而C3p0作為一個獨立的Bundle,不能偶合具體的驅動程序包,所以C3p0在創建數據庫連接池時,需要我們提供一個Fragment來讓其導入我們指定的驅動程序包,這曾在系列一中也已經說到過。但這里我們將不通過提供另一個Fragment來實現此需求,因為我想使用最新版的Mysql connector 5.1.13,但這個版本的Mysql connectorEBR倉庫中尚不存在,因此我借這個封裝Mysql connector的機會來解決C3p0使用mysql的驅動包的問題,并向大家介紹如何使用pax-construts來創建warpper工程。

          大致流程是:在命令行窗口下,進入到osgiapp/osgiapp-warpper目錄下,運行pax-construts創建warpper工程的命令,然后修改相關的配置文件,編譯打包即可。

          具體步驟如下:

          1. 創建osgiapp-warpper-mysqlconnector

          這里的mysqlconnector跟與面的cglib都是通過改造第三方的包來達到目的的,因此我們將其統統放在了warpper模塊之中,但這里的mysqlconnectorcglib還是有區別的,cglib是通過pax-construtspax-create-bundle命令創建的,而這里我們將通過pax-wrap-jar的命令來創建。命令如下:

          這里的-g、-a、-v跟之前的含義是一樣的,分別表示groupId、artifactId、version,但這里的這些指是的將要被我們包裝的Jar包的Maven屬性。如果此Jar包不存在本地的Maven倉庫中,Maven將會從網上的Maven2的倉庫中下載此Jar文件。

          2. 修改相關配置

          成功創建工mysql-connectorwarpper工程后,我們需要修改的有pom.xml文件跟osgi.bnd文件。

          修改pom.xml文件中的artifactIdosgiapp-warpper-mysql-connector-java,并將version改成5.1.13-001,還有就是properties中的bundle.symbolicName成改org.ideawork.osgiapp.wrapper.mysql.connector.java

          另外在osgi.bnd文件中添加如下信息:

          pax-wrap-jar -g mysql -a mysql-connector-java -v 5.1.13

          3. 編譯打包

          編譯打包直接運行Maven的命令即可。

          Tomcat提供Fragment

          為了使此web應用能正常訪問,我們需要為Tomcat 相關的兩個Bundle提供兩個Fragment。這在系列一中曾有說到。

          需要使用到這兩個FragmentBundleartifactId分別是:com.springsource.org.apache.catalinacatalina.start.osgi,前者是apache公司下的包,后者是springframeworkspringDMweb支持而提供的。

          具體的創建步驟如下:

          1. 新建fragment的模塊

          通過Pax-Construct的命令來新建此fragment模塊,如下:

          Import-Package = ""

          DynamicImport-Package = *

          Fragment-Host = com.springsource.com.mchange.v2.c3p0

          2. 新建兩個Fragmentbundle工程

          Cglibbundle工程的創建跟上篇中其他bundle的創建類似,命令如下:

          3. 修改配置文件

          將新建的Fragment工程導入到IDE環境,導入后工程視圖如下:


          這里我們只需簡單的修改一下兩個Fragment Bundle工程下的osgi.bnd文件并在工程的資源文件夾下添加幾個配置文件即可。

          a) 對于osgiapp-fragment-tomcat-conf這個Fragment,需要為其添加以下這四個配置文件,如圖:

             

          這四個配置文件來自于普通的tomcat安裝包中,不過需要版本匹配才行。比如這里用到的tomcat bundle6.0.15的那就需要從6.0.15版的傳統的tomcat的安裝目錄下拷貝。

          然后修改其osgi.bnd文件,此osgi.bnd文件中的內容如下:

          >cd osgiapp

          >pax-create-module -g org.ideawork.osgiapp -a osgiapp-fragment -v 1.0.0

          >cd osgiapp-fragment

          >pax-create-bundle -p org.ideawork.osgiapp.fragment.tomcat.conf -n osgiapp-fragment-tomcat-conf -g org.ideawork.osgiapp.fragment -v 1.0.0

          >pax-create-bundle -p org.ideawork.osgiapp.fragment.tomcat.start.conf -n osgiapp-fragment-tomcat-start-conf -g org.ideawork.osgiapp.fragment -v 1.0.0

          此處的Fragment-Host=com.springsource.org.apache.catalina指當前這個Fragment的宿主為com.springsource.org.apache.catalinabundle,Fragment-Host的值表示的是宿主BundleBundle-SymbolicName。

          b) 對于osgiapp-fragment-tomcat-start-conf Fragment,需要像上面的一樣添加一個server.xml的配置文件,這個文件的來由跟上面所說的一樣。添加后的視圖如下:

             

          然后再修改其osgi.bnd文件,內容如下:

          Export-Package = ""

          Private-Package = 

          Import-Package = ""

          Fragment-Host = com.springsource.org.apache.catalina


          總結

          通過以上的操作得到四個bundle,這四個bundle是這個OSGiweb應用所必須的,當然這樣的車輪只需要造一次,當你將需要再新建此類基于OSGi環境的SSH Web工程時,就可以直接拿過來用了。其中Tomcat的兩個Fragment主要是主含些配置文件,這個在項目部署的時候可能會需要修改的,具體得視應用而定。

          完成了這章中的四個Bundle后,我們可以將這四個Bundle應用于系列三中的框架中來進行測試。也許這章的內容應該位于上篇之前介紹,大家就當這是對前一篇的補充吧。


          附件:項目源碼 osgiapp.zip

          posted on 2010-06-26 16:24 瀟湘振宇 閱讀(3820) 評論(5)  編輯  收藏 所屬分類: OSGi系列

          Feedback

          # re: 基于OSGi的Web應用開發系列四(提供支撐的Bundles)[未登錄] 2010-06-28 16:33 root
          很強大,支持下  回復  更多評論
            

          # re: 基于OSGi的Web應用開發系列四(提供支撐的Bundles) 2010-07-23 23:52 zhangls
          謝謝作者能和大家分享OSGi成果~ 本人最近也在研究osgi,能否發我一份源碼,希望能有更多的交流。謝謝~!  回復  更多評論
            

          # re: 基于OSGi的Web應用開發系列四(提供支撐的Bundles) 2010-07-23 23:53 zhangls
          email:zhanglingsi@yahoo.com.cn   回復  更多評論
            

          # re: 基于OSGi的Web應用開發系列四(提供支撐的Bundles) 2010-07-28 09:24 瀟湘振宇
          @zhangls
          源碼就在本篇的末尾,只是因為最近公司事忙,沒有繼續這系列文章的編寫,將上面源碼包導入到Eclipse中,再用Maven命令來編譯打包安裝后,再用mvn pax:provision的命令就可以啟動這個OSGi web應用,只是系列文章中說到的用戶登錄的功能尚未實現。但那只是業務方面,整體的開發腳手架已經搭建起來了,運行也是沒問題的。
          如果對這里說到的運行的命令不懂,可以仔細閱讀本系列前幾篇文章。  回復  更多評論
            

          # re: 基于OSGi的Web應用開發系列四(提供支撐的Bundles) 2010-08-10 09:36 瀟湘振宇
          關于mvn-pax-plugin插件,這里給出兩個開發過程中常用的參數,如下:
          <param>--vmOptions=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000</param>
          <param>--repositories=+http://scm.ops4j.org/repos/ops4j/projects/pax/runner-repository/</param>
          其中--vmOptions參數是指設置JVM的一些屬性,如上所示開啟遠程Java調試。
          而--repositories是pax自己的一個參數來著。有時候在用pax:provision命令時,其老是去訪問網絡下載或檢測相關pax的包,浪費掉了我們開發人員寶貴的時間,加上這個參數后會好很多。  回復  更多評論
            

          主站蜘蛛池模板: 濮阳县| 奉新县| 沈丘县| 阿拉善右旗| 南部县| 烟台市| 深水埗区| 从江县| 新宾| 蕉岭县| 行唐县| 昌平区| 永修县| 武穴市| 济源市| 台前县| 即墨市| 建湖县| 读书| 元氏县| 芜湖市| 彩票| 商都县| 普洱| 格尔木市| 英超| 石渠县| 五常市| 墨江| 临澧县| 吐鲁番市| 会同县| 正宁县| 清丰县| 金川县| 页游| 抚州市| 新蔡县| 孟州市| 芦山县| 金阳县|