版權聲明:任何獲得Matrix授權的網站,轉載時請務必保留以下作者信息和鏈接
用戶可能遇到什么樣的問題呢?首先,如果用戶沒有完全按照正確的安裝步驟,在安裝過程中就可能會出現問題了。即使安裝成功了,之后問題仍然可能出現。配置(像JAVA_HOME環境變量)的改變或者目錄結構的改變無疑會導致問題。
在本文中,我們將要開發一個Ant腳本來為一個Java程序運行診斷測試。我們將著眼于建立一個可能出現的問題的列表以及如何來解決這些問題。Ant需要提前被安裝在用戶的機器上,這意味著你的安裝程序可能需要提供Ant。
系統配置
在除錯時你需要知道的第一件事就是系統配置——操作系統,Java版本,類路徑等等。由于Ant提供了對所有Java系統屬性的訪問,實現這一功能是很容易的。下面是一個示例:
示例將有如下輸出:$ ant -f diagnostic.xml
現在,如果哪個方面出現了問題,你就可以在系統屬性中找到問題的源頭了,比如錯誤的Java版本或者類路徑等等。
Buildfile: diagnostic.xml
systemProperties:
[echo] Java Runtime Environment version:
1.4.2_05
[echo] Java Runtime Environment vendor:
Apple Computer, Inc.
[echo] Java Runtime Environment vendor URL:
http://apple.com/
...
[echo] Default temp file path: /tmp
[echo] Operating system name: Mac OS X
[echo] Operating system architecture: ppc
[echo] Operating system version: 10.3.9
文件和類路徑的有效性
我們可以進一步實現一些自動測試來檢測一個文件或類能否被找到:
第一個目標執行兩項測試:首先它檢查org.apache.fop.apps.Fop類能否在類路徑中被找到,然后檢查目錄directory build/scripts是否存在。將type改為file的話,有效性測試就可以檢查指定文件是否存在。如果類或者目錄不存在的話,后面兩個目標將分別顯示出錯誤信息。
Java版本的最低需求
我們可以做更多,但是這需要我們編寫定制的Ant任務。我們就來檢查一下已經安裝的Java版本是否高于我們的代碼所要求的最低版本。如果版本不符合要求,診斷編譯文件就會提示錯誤信息。JavaVersionTask類的源代碼如下:import org.apache.tools.ant.*;
/**
JavaVersionTask is an Ant task for testing if
the installed Java version is greater than a
minimum required version.
**/
public class JavaVersionTask extends Task {
// Minimum required Java version.
private String minVersion;
// Installed Java version.
private String installedVersion;
// The name of the property that gets set when
// the installed Java version is ok.
private String propertyName;
/**
* Constructor of the JavaVersionTask class.
**/
public JavaVersionTask() {
super();
installedVersion = System.getProperty
("java.version");
}
/**
* Set the attribute minVersion.
**/
public void setMinVersion(String version) {
minVersion = version;
}
/**
Set the property name that the task sets when
the installed Java version is ok.
**/
public void setProperty(String propName) {
propertyName = propName;
}
/**
* Execute the task.
**/
public void execute() throws BuildException {
if (propertyName==null) {
throw new BuildException("No property name
set.");
} else if (minVersion==null) {
throw new BuildException("No minimum version
set.");
}
if(installedVersion.compareTo(minVersion)
>= 0) {
getProject().setProperty(propertyName,
"true");
}
}
}
如果你建立一個定制任務,它的類需要擴展org.apache.tools.ant.Task類。任務的編譯文件中每一個屬性都使用一個設置方法來設置,方法的名字以“set”開頭,接著是屬性的名字,名字的首字母需要大寫(這是JavaBeans的約定)。例如,屬性minVersion使用方法setMinVersion來設置,同樣屬性property使用方法setProperty來設置。
當編譯文件調用任務的時候,方法execute將被執行。首先我們檢查屬性是否已被設置,然后我們執行任務的核心:如果已安裝的Java版本高于或者等同于最低要求的Java版本,我們就把指定名字的屬性值設為真。
版本以字符串對象的形式儲存,因此我們可以用按照字母順序來比較兩個字符串的compareTo方法來比較它們。如果第一個串小于第二個串,該方法則返回-1,相等則返回0,如果第一個串按照字母順序大于第二個串則返回+1。這樣任務就可以認為1.5大于1.4,也大于1.4.2或者1.4.2_05。
為了在Ant編譯文件中使用定制任務,我們首先需要定義一個包含最低所需Java版本的編譯屬性:
在目標systemProperties中我們加入下列代碼:
第一行定義了一個名叫javaversion的新任務,接著是實現這一任務的Java類名:JavaVersionTask。下一行執行指定了最低所需Java版本的javaversion任務。當已安裝的Java版本高于所需版本時,javaversion.ok則被賦值。
然后我們加入一個目標javaVersion:
接下來,我們把目標加入到目標all的依存關系中。它只有在javaversion.ok屬性沒有被設置的時候才執行。此時,目標將顯示一條錯誤信息,提示出找到的Java版本和所需的Java版本。這是一個輸出的示例:javaVersion: [echo] ERROR: Java version
與JavaVersionTask相似,我們也可以寫一個任務來執行其他的版本檢查,例如已安裝的庫或者操作系統的版本。
too old: found 1.4.2_05, needs 1.5.
被改變的文件
當問題發生時,了解在安裝之后是否有文件被改變是十分重要的。有可能是標準配置被改變或者被替換掉的文件引起了問題。為了調查這一點,我們可以使用Ant的校驗和:在我們軟件的安裝編譯文件中,我們為每一個文件生成一個校驗和,在診斷測試中我們就可以驗證這些校驗和。這樣我們就可以在安裝之后了解哪個文件被改變了,并且該任務縮小了搜索引起問題原因的范圍。在安裝編譯文件中,我們可以為每個可能被改變的重要文件生成一個MD5校驗和,在診斷編譯文件中我們就可以校驗它。當然,被改變的二進制文件與被改變的配置文件是有區別的,前者不應該被改變,后者被改變了就可能會引起問題,也可能不會。
在我們的安裝編譯文件中,我們像這樣來生成校驗和:
Ant為build目錄及其子目錄中所有擴展名為.class的文件生成MD5校驗和。校驗和將以原文件名保存,加上擴展名.MD5。對于配置文件config.xml也是一樣。在所有的文件都被編譯之后,目標checksum就將被執行。
在診斷編譯文件中,我們驗證校驗和:
將目標加入到目標all的依存關系中。
首先,目標checksum將被執行。如果所有類文件的校驗和與之前所生成的校驗和相符,屬性binary.unchanged將被設為真。但如果至少一個文件被改變了,該屬性則不會被賦值。然后,如果config.xml文件沒有被改變,屬性config.unchanged則被設為真。依賴于目標checksum的目標binaryChanged只有在binary.unchanged沒有值的時候才被執行,也就是在至少一個類文件被改變的時候,然后將輸出一條錯誤信息。對于配置文件也是一樣,但是我們將輸出一條警告信息。
如果沒有文件被改變,我們的診斷編譯腳本輸出入下信息:checksum:
[echo] Verifying checksums of binary files...
[echo] Verifying checksum of configuration file...
binaryChanged:
configChanged:
all:
BUILD SUCCESSFUL
Total time: 1 second
假設我們改變了配置文件,然后我們會得到這樣的輸出:checksum:
[echo] Verifying checksums of binary files...
[echo] Verifying checksum of configuration file...
binaryChanged:
configChanged:
[echo] WARNING: Configuration file changed.
all:
BUILD SUCCESSFUL
Total time: 1 second
如果我們的軟件開放源代碼,我們可以做得更好,甚至可以將被改變的文件恢復成標準版本。對于特定的類文件,這意味著我們需要編譯Java文件。當然,你的客戶需要擁有完整的JDK(不只是Java運行時)和你的源代碼及其編譯文件。為了恢復被改變的類文件,我們刪除他們然后調用安裝編譯文件的編譯任務。這一任務的細節取決于你的編譯系統。
作為另外一種選擇(例如你的軟件為封閉源代碼),你可以在安全的位置將已知為正確版本的類文件存放在一個.jar或者.zip文件中并且解包它們。然后你就可以使用已知的正確版本來替換被改變的類文件了。
另一方面,配置文件可以從源文件夾中拷貝過來。我們可以適當地擴展目標configChanged并且添加一個目標configRestore來實現這一功能:
addproperty="config.restore"/>
將目標加入到目標all的依存關系中。如果配置文件被改變,Ant將詢問用戶是否希望備份該配置文件并且恢復為初始狀態。如果用戶按下了“Y”和回車鍵來選擇“Yes”,屬性config.copy將被設置,目標configRestore只有在這一屬性被設置的情況下才會執行,它備份build/config.xml 為 build/config.xml.1,然后將原始的src/config.xml 拷貝為 build/config.xml。
結論
我們開發了一個Ant腳本來為Java應用軟件執行診斷測試,該腳本檢查已安裝的Java版本是否符合最低要求,一些重要文件是否被改變,一個指定的Java類是否在類路徑中,一個目錄是否存在等等。在檢查了軟件的所有先決條件之后,腳本將結果報告給用戶。該腳本甚至可以修復一些問題。另外,診斷腳本的輸出也可以為技術支持人員所用,來快速地幫助用戶,而不需要問上一大堆的問題。
資源
· 本文的源代碼
· Apache Ant計劃
· Apache Ant用戶指南
· "Writing Ant Tasks"
Koen Vervloesem擁有計算機科學的碩士學位,從2000年開始成為IT自由撰稿人,主要為荷蘭的IT期刊撰稿。
原文:http://www.javaworld.com/
譯文:http://www.matrix.org.cn/
原文轉自:http://www.anti-gravitydesign.com