背景介紹
RCP 簡介
RCP(Rich Client Platform),即富客戶端平台,是一個基於 Eclipse 的開源技術框架,它可以給開發人員提供豐富的 組件來構建一個應用,避免了從零開始的繁重開發任務,從而能夠快速的完成應用程序的開發工作,開發人員就可以通過把 更多的精力放在業務組件開發上來擺脫枯燥的界面布局等開發工作。同時,RCP 也可以讓從未有過插件開發的開發人員更容 易上手和了解插件開發的概念。
Ant 簡介
Ant 是用 Java 語言編寫的項目管理工具。它可以通過構建 XML 的配置文件來管理和部署項目。
問題的提出
利用 RCP 的特點可以縮短軟件開發的周期,提高開發效率,然而,在實際開發中,生成產品的編譯環境和開發人員使用 的開發環境往往是不在同一個服務器或者機器上。對於有可視化界面的操作系統,我們也許可以通過界面向導方式生成最終 產品。但是對於那些非可視化界面的編譯環境,該如何生成產品呢?與 Ant 相結合,可以很好的解決這一問題。下面進行 詳細介紹。
環境准備
准備 Ant 環境
下載 Ant 安裝包
在 Apache 官網下載 Ant 包,相關鏈 接在參考資料。
配置環境變量
在環境變量裡添加 ANT_HOME=C:\Test\Ant\apache-ant-1.8.4。
在 Path 裡添加 %ANT_HOME%/bin 的路徑。
檢查 Ant 安裝
以 Windows 為例,控制台裡輸入 ant - version。如果輸出的是當前的 Ant 的版本並且沒有報錯,那說明 Ant 的環境變量配置已經好了。
准備 Eclipse
下載一個 Eclipse SDK 開發工具和與之對應的 Eclipse delta pack。在 delta pack 裡包含了很多平台打 包時所依賴的 jar 包。具體鏈接可以參照參考資料裡的鏈接。
實際案例
通過上述的介紹,大家對 RCP 和 Ant 有了一個初步的了解。下文將通過一個例子來說明如何用 Ant 腳本來部署一個 RCP 項目。
創建 RCP 項目
步驟一:建立一個 RCP 的簡單工程項目。
選擇 plug-in Project 工程。
圖 1. 創建插件工程
命名工 程名字為 HelloRCP,然後進入下一步,在選擇模板的向導頁裡選擇,“Hello RCP”模板如圖所示:
圖 2 創建工程 模板
這 個模板包含了一個標准的 RCP 工程所需要的包。項目創建好後,創建一個 product 文件,該文件用於定義生成產品所包含 的依賴包、產品的信息等。
圖 3. 項目文件結構
項目建立好後,下一步我們就可以開始編寫 Ant 的 build 腳本了。
自定義 Ant 腳本
在 Ant 腳本的編寫時,涉及到兩個文件,一個是 build.xml,在 這裡用來定義對項目部署的整個流程。另一個是 build.properties,這個文件主要用來定義 build.xml 文件裡用到的變量 值。構建 Ant 腳本,可以通過圖的形式來描述它們彼此之間的依賴關系。
圖 4. Target 關系圖
從圖中可以看出 ,各個 Target 間的依賴關系,可以更有利於理解和編寫 Ant 腳本。build.xml 文件的內容如下 :
清單 1.build.xml
<project name="HelloRCP" default="start"> <property file="build.properties" /> <!-- bootstrap --> <target name="start"> <antcall target="external" /> <antcall target="deploy" /> </target> <!-- invocation external build.xml --> <target name="external"> <ant antfile="build.xml" dir="${external_build}"/> </target> <!-- start export rcp product --> <target name="init"> <mkdir dir="${buildDirectory}" /> <mkdir dir="${buildDirectory}/plugins" /> <copy todir="${buildDirectory}/plugins"> <fileset dir="../../"> <!-- include source codes needed to be built.--> <include name="HelloRCP/**" /> </fileset> </copy> </target> <target name="pde-build"> <java classname="org.eclipse.equinox.launcher.Main" fork="true" failonerror="true"> <arg value="-application" /> <arg value="org.eclipse.ant.core.antRunner" /> <arg value="-buildfile" /> <arg value="${eclipseLocation}/plugins/ org.eclipse.pde.build_${pdeBuildPluginVersion}/ scripts/productBuild/productBuild.xml" /> <arg value="-Dtimestamp=${timestamp}" /> <classpath> <pathelement location="${eclipseLocation}/plugins/ org.eclipse.equinox.launcher_${equinoxLauncherPluginVersion}.jar" /> </classpath> </java> </target> <target name="build" depends="clean, init, pde-build" /> <!-- end rcp export product--> <!-- merge configure file --> <target name="deploy" depends="build"> <!-- --> </target> <!-- end merge configure file --> <!-- clean all temp file--> <target name="clean"> <delete dir="${buildDirectory}" /> </target> </project>
那麼,每個 target 在這個 Ant 腳本裡具體的角色是什麼呢?
<target name="start">:是整個 Ant 腳本的啟動 target,類似於一個類裡的 main 方法。
<target name="deploy">:對項目配置文件的部署,比如需要的外部 jar、properties 文件等。
<target name="build">:對代碼進行編譯,並生成 RCP 的產品文件,包括執行文件,配置文件、相關的插件和產品 的信息文件。
<target name="pre-build">:調用 Eclipse 的導出功能生成產品。
<target name="clean">:清除在編譯過程中產生的臨時文件。
<target name="init">:部署代碼到指定位置,為編譯做准備。
<target name="external"> :用來調用其他 Ant 腳本。
下面對 build.xml 做一個簡單的說明:
在一個 Ant 腳本裡只包含一個 project 元素,並且 default 屬性值定義的就是 Ant 腳本初始調用的 target,如 <project name="HelloRCP" default="start">,在這裡 start target 被定義為初始被執行的 target。
對於 target 的調用這裡用到了兩種方法,一種是通過 depends 屬性,來找到當前 target 所依賴的 target。比 如 <target name="deploy" depends="build">在 deploy 這個 target 裡,設置了 depends 這個屬性,所以在這裡會先去調用 build 這個 target,當 build target 執行完,再來執行 deploy target。depends 屬 性還可以指定多個 target,比如,<target name="build" depends="clean, init, pde-build" />在對 Ant 的 build.xml 腳本解析的時候會按順序依次的調用這三個 target。另一種是通過 antcall 這個元素來調 用 target,如 <antcall target=" external " />,直接通過 target 的名字來調用指定的 target。在 這裡調用到了 external target。
在實際工作中,可能某個工程已經有了自己的 Ant 腳本,而我們所需要做的就是 調用這個腳本,如 external target 就是定義了一個外部腳本的調用,<ant antfile="ex_build.xml" dir="${external_app_destdir}"/>這個 external_app_destdir 名字就是用來定義另一個 Ant 腳本的具體 位置,所以在框架解析到這個 target 的時候,會到指定的目錄裡去找名字為 ex_build.xml 的 Ant 腳本,這裡要提醒的 是,在 build.xml 定義的變量是可以被外部的編譯腳本使用,但如果變量定義的值涉及到相對路徑的時候,在對外部腳本 解析的時候,框架會將這個 ex_build.xml 作為當前的編譯目錄,所以在 ex_build.xml 使用 build.xml 中定義的相對路 徑的時候,很容易產生路徑文件找不到的編譯錯誤,在編寫腳本相對路徑的時候,要明確這個相對路徑是相對當前哪個 Ant 腳本來定義的。
清單 2.init target
<target name="init"> <mkdir dir="${buildDirectory}" /> <mkdir dir="${buildDirectory}/plugins" /> <copy todir="${buildDirectory}/plugins"> <fileset dir="../../"> <include name="HelloRCP/**" /> <!-- include source codes needed to be built.--> </fileset> </copy> </target>
在 init target 裡,首先是創建了 build 的路徑,然後將源代碼拷貝到 plugins 裡,之所以 構建這個目錄結構,是因為要滿足在 Eclipse 的 PDE 框架裡的目錄結構,框架會從這個目錄裡取得源代碼,然後進行相應 的編譯操作。這裡的相對路徑的寫法是以當前的 build.xml 的路徑為基准的。** 表示的是指定 HelloRCP 這個目錄下的所 有文件及子文件夾。當然如果有多個工程需要進行編譯操作在 fileset 這個元素下 , 可以指定多個 include 元素。
清單 3 pde-build target
<target name="pde-build"> <java classname="org.eclipse.equinox.launcher.Main" fork="true" failonerror="true"> <arg value="-application" /> <arg value="org.eclipse.ant.core.antRunner" /> <arg value="-buildfile" /> <arg value="${eclipseLocation}/ plugins/org.eclipse.pde.build_${pdeBuildPluginVersion} /scripts/productBuild/productBuild.xml" /> <arg value="-Dtimestamp=${timestamp}" /> <classpath> <pathelement location="${eclipseLocation}/plugins /org.eclipse.equinox.launcher_ ${equinoxLauncherPluginVersion}.jar" /> </classpath> </java> </target>
這部分是將工程編譯產品的核心。首先,是運行 org.eclipse.equinox.launcher.Main 這個類 ,在這裡要傳入的幾個參數,例如調用的具體的 antRunner、pde 的 jar 包等等。org.eclipse.ant.core.antRunner 用來 解析運行 Ant 編譯腳本的文件,裡面提供了一些方法來設置那些在 build 過程中用的類,productBuild.xml 就是指在當 前使用的 Eclipse 裡 pde 要用到的生成產品的編譯文件,具體位置就是 org.eclipse.pde.build 加上具體相應的版本號 的文件夾的位置裡。在 productBuild.xml 的腳本裡,可以看出在生成產品的時候會對相應的依賴的 jar 包進行依賴性的 檢查和生成,在這裡很容易出現在編譯的時候對某個 jar 文件的丟失,導致 Ant 腳本生成時候的報錯。如果有類似缺失依 賴包的問題出現,就去工程裡的 .product 的 dependencies 裡導入相應的 jar 包。
到此,對一個 build.xml 的 簡單介紹就完成了,對於 Ant 腳本來說,能夠完成的任務是非常豐富的,如並發,條件執行,編譯,取得系統的環境變量 等等,有興趣的話可以參考 developer works 裡對 Ant 的專題介紹。
Ant 腳本的配置文件
在 Ant 腳本裡 有兩種主要有兩種方式,一種是通過對 property 元素直接賦值,另一種是通過 build.properties 文件來定義變量的值, 這種方式更有利於維護和可讀性。本案例就是使用配置文件的方式來定義變量。build.xml 要先對配置文件進行導入,才會 在 Ant 腳本裡識別出變量的值。在默認情況下,build 的 xml 文件和配置文件在同一路徑下,也可以去指定這個配置文件 的具體位置。下面是 build.properties 文件的具體內容:
清單 4 build.properties
pdeBuildPluginVersion=3.8.0.v20120523-1555 equinoxLauncherPluginVersion=1.3.0.v20120522-1813 eclipseLocation=C:/eclipse-rcp-juno-win32-x86_64/eclipse product=HelloRCP/hellorcp.product runPackager=true archivePrefix=HelloRCP collectingFolder=${archivePrefix} configs=win32, win32, x86_64 allowBinaryCycles = true flattenDependencies = true buildDirectory=C:/DW buildId=hellorcp buildLabel=${buildType}.${buildId} timestamp=007 baseLocation=C:/eclipse-rcp-juno-win32-x86_64/eclipse baseos=win32 basews=win32 basearch=x86_64 filteredDependencyCheck=false resolution.devMode=false skipBase=true skipMaps=true mapsRepo=:pserver:[email protected]/path/to/repo mapsRoot=path/to/maps mapsCheckoutTag=HEAD mapsTagTag=v${buildId} skipFetch=true JavaSE-1.6=${java.home}/lib/rt.jar logExtension=.log javacDebugInfo=true javacFailOnError=true javacVerbose=true javacSource=1.6 javacTarget=1.6 external_build=C:/external
下面對 build 的配置文件做個簡單的說明:
pdeBuildPluginVersion=3.8.0.v20120523-1555
用來指定 Eclipse 裡 pde 的版本,這個可以在 Eclipse 的 plugin 文件夾下找到。
equinoxLauncherPluginVersion=1.3.0.v20120522-1813
指定 org.eclipse.equinox.launcher 的版本,同樣也是在在 Eclipse 的 plugin 文件夾下。
eclipseLocation=C:/eclipse-rcp-juno-win32-x86_64/eclipse
這個變量是用來設置運行的 Eclipse 的具體文件路 徑。
buildDirectory=C:/DW
用來設置編譯生成產品的具體位置。
configs=win32, win32, x86_64
用來設置生成產品的具體運行在什麼樣的操作系統上。這裡指定的是 windows 64 位的。
buildId=hellorcp
導出產品的具體名稱,要區分的是這個不是具體執行文件的名字而是生成產品文件夾的名字。到 此一個 RCP 項目的建立,一個標准的 Ant 腳本和配置文件的編寫就完成了。
運行
對於編寫好的 Ant 腳本 有兩種方式可以運行,一種是通過 Eclipse 的圖形界面 ( 右鍵工程裡的 build.xml -> Run As -> Ant Build),在 Eclipse 的控制台會打印出運行 Ant 腳本時的一些輸出信息。另一種方式就是通過命令的方式在一個搭建好 Ant 環境的平 台上運行如:ant <build.xml> 這樣的命令來執行 Ant 腳本。第二種方式比較方便,因為我們可以直接以命令行的 方式去打包我們要的產品,而不需要通過運行 Eclipse 來完成我們的操作,而且如果是通過遠程機器來打包我們的產品時 ,我們也只需要傳遞一條命令,就可以完成部署工作了。我們通過命令方式來運行之前我們寫好的 Ant 腳本文件。運行如 下的命令:
C:\workspace_rcp\HelloRCP\builds> ant
可以在控制台裡看到 Ant 的編譯信息,直到編譯成功結束。現在我們可以看到已經部署好了我們要的產品。在 pde 的 框架裡,會對這個產品輸出自動打成一個壓縮包,根據具體項目需要我們可以編寫腳本將我們需要的配置文件也放到這個壓 縮包裡。如果有的開發人員覺得這個運行命令的方式不是很方便的話我們也可以寫一個批處理文件,以 windows 為例,下 面我們來寫一個 .bat 文件,內容如下:
清單 4 Auto.bat
call C:\Test\Ant\apache-ant-1.8.4\bin\ant.bat -file
C:\workspace_rcp\HelloRCP\builds\build.xml
這樣以後如果有代碼的更新時,我們只要運行這個 bat 文件就可以了。我們可以看到,通過命令方式運行的結果與 Eclipse 界面方式的導出是一樣的,並且這種方式也節省在項目部署時候的時間,提高了效率。
常見問題
用 product 運行時報找不到 application id 的錯誤怎麼辦 ?
答:打開 product 這個文件,在 overview 裡的 product definition 標簽中配置 product 和 application。
找不到 tools.jar 怎麼辦 ?
答:有的時候在配置 Ant 時,會遇到 tools.jar 找不到,最直接的方式就是把 jdk 裡的這個 jar 賦值到錯誤提示裡的 jre 的目錄裡。
找 不到依賴包怎麼辦 ?
答:如果在運行 Ant 腳本的時候,提示有 jar 包缺失,在 product 的 dependencies 裡添加 缺少的依賴包。
如何生成多平台的產品 ?
答:如果要生成多平台的產品時,只需要修改 build.properties 裡的 configs 屬性的值,如:configs= win32,win32,x86 & linux, gtk, x86_64 這樣就會生成 Windows 32 位和 Linux 64 位的產品。
總結
本文已經將 Eclipse RCP 與 Ant 工具的結合使用介紹給大家了,在實際的項目操作中 ,我們不但可以利用 Eclipse RCP 的特點可以提高我們的開發速度,同時在結合了 Ant 之後,也提高了項目後期效率。希 望本文的介紹可以給讀者在實際的開發中提供一定的幫助。