趙彥紅
通號工程局集團(tuán)北京研究設(shè)計(jì)實(shí)驗(yàn)中心有限公司 北京 100070
隨著近來軟件行業(yè)的迅猛發(fā)展,以及人們對軟件需求的日益增長,軟件的質(zhì)量越來越成為人們關(guān)注的對象,保證軟件質(zhì)量的途徑有兩種:一種是設(shè)計(jì)階段盡量避免缺陷,另一種就是軟件開發(fā)完成后的測試。軟件的測試按功能性可分為白盒測試、黑盒測試和灰盒測試;從是否執(zhí)行程序角度可分為動態(tài)測試和靜態(tài)測試。本文主要研究的是靜態(tài)測試,靜態(tài)測試不實(shí)際運(yùn)行軟件,主要對軟件的編程格式、結(jié)構(gòu)等方面進(jìn)行評估。靜態(tài)測試包括代碼規(guī)范性檢查、靜態(tài)結(jié)構(gòu)分析和代碼質(zhì)量檢查等,可人工完成,也可借助軟件工具進(jìn)行。靜態(tài)分析工具能自動找出代碼中已有的缺陷[1]。好的靜態(tài)分析工具是測試過程中不可或缺的利器,可在短時(shí)間內(nèi)通過分析或檢查源程序的語法、結(jié)構(gòu)、過程、接口等來檢查程序的正確性,找出代碼隱藏的錯(cuò)誤和缺陷,如參數(shù)不匹配,有歧義的嵌套語句,錯(cuò)誤的遞歸,可能出現(xiàn)的空指針引用等[2]。
Eclipse是一款開源的基于java的可擴(kuò)展開發(fā)平臺。開源性決定了任何人都可以對Eclipse實(shí)施開發(fā)插件的過程,可擴(kuò)展決定了java功能的可完善性和易維護(hù)性。所以,Eclipse插件就是集成在Eclipse平臺中的實(shí)現(xiàn)不同功能的工具。
Find Bugs是一個(gè)能靜態(tài)分析源代碼中可能會出現(xiàn)bug的Eclipse插件工具。它檢查類文件,將字節(jié)碼(bytecode存在于編譯后的.class文件中)與一組缺陷模式和集成的規(guī)范進(jìn)行對比以發(fā)現(xiàn)可能的問題。有了靜態(tài)分析工具,就可以在不實(shí)際運(yùn)行程序中對源代碼進(jìn)行分析。不是通過分析類文件(.class的文件) 的形式或結(jié)構(gòu)來確定程序的意圖,而是使用Visitor模式[3]對文件進(jìn)行掃描和分析,在不改變源代碼的情況下,檢測出源代碼中的存在的潛在性問題。
Find Bugs是由許多不同特性的JAR文件組成,這些JAR文件可以通過Eclipse運(yùn)行實(shí)現(xiàn)自己的功能。而這些功能是可選的,所以在進(jìn)行測試時(shí),可以根據(jù)需要來選擇功能。這正是Find Bugs的方便之處,也是插件開發(fā)者能夠進(jìn)行方便開發(fā)的前提。
開發(fā)流程圖如下:
圖1 開發(fā)流程圖
進(jìn)行Java開發(fā)過程中,Eclipse的使用是不可避免的,而基于Eclipse的Find Bugs插件在前期能夠減少代碼出現(xiàn)錯(cuò)誤和避免不好的編碼習(xí)慣。
Find Bugs將檢測到的錯(cuò)誤分為以下幾類:Bad practice,Correctness,Internationalization,Malicious code vulnerability,Multithreaded correctness,Performance,Dodgy code,Security,Experimental??梢奆ind Bugs插件不僅是檢查代碼的漏洞和錯(cuò)誤,還會檢查代碼的書寫習(xí)慣、安全性能、多線程以及國際通用性等問題。
本文設(shè)計(jì)的插件就是屬于Find Bugs中的Bad practice,本文所開發(fā)的插件主要檢查Java代碼中空的try/catch塊。眾所周知,異常檢測在Java開發(fā)中是一個(gè)重要的環(huán)節(jié),其語句如下:
其中try語句用來捕獲異常,而catch語句用來打印異常信息。異常信息對于Java代碼的調(diào)試非常重要,如果不輸出異常信息,Java檢測機(jī)制不會報(bào)錯(cuò),代碼本身也沒有錯(cuò),這樣會產(chǎn)生一種情況:當(dāng)代碼出現(xiàn)可以被捕獲的錯(cuò)誤后,無法知道這種錯(cuò)誤是什么和這種錯(cuò)誤出現(xiàn)的具體位置。所以,本文闡述的插件功能屬于Find Bugs中bad practice一類。
本文設(shè)計(jì)中,使用了Hashmap數(shù)據(jù)結(jié)構(gòu),Hashmap用來存儲鍵值對,key值為Java源代碼中的方法名稱,而value值則為byte code中象征catch內(nèi)容為空的標(biāo)志關(guān)鍵字。例如,本文中我們將要存儲的方法名或關(guān)鍵字用形參mName(方法的名稱)來代替,對應(yīng)在字節(jié)碼中相應(yīng)的value有不同的值,我們用統(tǒng)一的形參seen代替,實(shí)現(xiàn)語句如下:
正常情況下的程序,也就是有異常但catch塊不為空,被處理的情況下的字節(jié)碼如下:
對比以上兩段代碼可以觀察到,第一段中的第11行astore_1將byteArray調(diào)用完成后直接返回,沒有經(jīng)過異常處理機(jī)制,即未經(jīng)過catch塊。第二段中第8行經(jīng)過astore_1后,進(jìn)行了異常處理函數(shù)的調(diào)用,其指令為第11行的invokevitual。所以,這將成為我們檢測空的catch塊的一種實(shí)施方案。部分源代碼如下:
由于Find Bugs是一款靜態(tài)分析工具,并且集成了不同檢測功能的插件,所以要想將本文中的功能集成到Find Bugs中去,最好的辦法就是應(yīng)用visitor設(shè)計(jì)模式。
Visitor模式的主要作用就是在不改變現(xiàn)有類的情況下,向其中添加新的方法。其序列圖如下:
圖2 visitor設(shè)計(jì)模式的序列圖
具體實(shí)現(xiàn)的部分源代碼如下:
完成插件的開發(fā)后會生成.jar文件,把.jar文件添加到Find Bugs插件中,再次重啟Eclipse可以看到在Find Bugs中已有新添加的插件。將Find Bugs新的插件應(yīng)用在測試用例上會看到,新的插件給出了錯(cuò)誤的具體位置以及錯(cuò)誤信息,如下圖:
圖3 新插件運(yùn)行在測試用例中的效果
整個(gè)過程用時(shí)1.15s,可以說是比較快,如果和其他插件功能同時(shí)運(yùn)行,基本上不會增加Find Bugs的運(yùn)行負(fù)擔(dān)。
本文介紹了基于Eclipse的Find Bugs插件的開發(fā),重點(diǎn)介紹了對檢測空的catch塊功能的研究與開發(fā)。由于Eclipse是一款開源平臺,所有基于Eclipse插件的開放性為廣大的開發(fā)者提供了良好的開發(fā)平臺,使開發(fā)者可以在遵循JVM規(guī)則的基礎(chǔ)之上,對必要的以及感興趣的功能做嘗試性開發(fā)。本文就是在充分了解JVM規(guī)則、Find Bugs運(yùn)行機(jī)制以及已存在的Find Bugs插件基礎(chǔ)上,對Find Bugs中檢測空catch塊的功能進(jìn)行了彌補(bǔ)和嘗試性的開發(fā),并得到了預(yù)期的效果。