本發(fā)明屬于軟件分析中的代碼克隆檢測
技術(shù)領(lǐng)域:
:,具體涉及到云環(huán)境下一種基于java字節(jié)碼的多粒度代碼克隆檢測方法。
背景技術(shù):
::云計算的出現(xiàn)為傳統(tǒng)軟件開發(fā)提供了一種新型的協(xié)同工作模式。在這種模式下,不同的軟件團隊和個人分布在不同地方,為共同開發(fā)同一個軟件系統(tǒng)作出貢獻?;谠骗h(huán)境的協(xié)同開發(fā)模式在給軟件開發(fā)人員帶來便利的同時也給軟件的管理帶來了一定的困難,特別地由于地域和團隊的不同,對開發(fā)人員通過復(fù)制-粘貼或者添加少量修改來復(fù)用代碼的行為缺乏有效的監(jiān)管。這些重復(fù)代碼(或稱之為代碼克隆)會嚴重影響軟件的維護工作。通過對軟件源碼中的代碼克隆進行檢測,可以發(fā)現(xiàn)不必要的重復(fù)代碼,從而為后續(xù)的代碼重構(gòu)提供支持?,F(xiàn)有的代碼克隆檢測技術(shù)主要有基于文本(text)、基于token、基于抽象語法樹(ast)、基于程序依賴圖(pdg)和基于度量值幾類?;趖ext的方法不需要對源代碼進行轉(zhuǎn)換,其準確率較高但是召回率底;基于token的方法檢測速度較快并且不依賴于開發(fā)語言,但是卻很難檢測type-3類代碼克??;基于ast和基于pdg的方法需要把源代碼轉(zhuǎn)換成ast或者pdg然后再進行相應(yīng)的比較,這兩種方法所花費的代價都比較大;由于不同的代碼段對應(yīng)的度量值可能會相同,所以基于度量值的方法誤報率較高。技術(shù)實現(xiàn)要素:本發(fā)明針對現(xiàn)有技術(shù)的不足,提供了一種云環(huán)境下基于java字節(jié)碼的多粒度代碼克隆檢測方法。本發(fā)明方法的具體步驟是:步驟(1)獲取云環(huán)境下分布于不同地點的java源代碼,編譯得到它們的字節(jié)碼文件即.class文件,并通過javap命令將.class文件轉(zhuǎn)換為txt格式文件;每個txt格式文件包含一個或多個java方法,每個方法都由一系列字節(jié)碼指令以及相關(guān)的方法調(diào)用構(gòu)成;步驟(2)提取步驟(1)中所得到的txt格式文件中的方法與代碼塊,其中,通過直接讀取每個方法所對應(yīng)的字節(jié)碼指令提取方法;代碼塊的提取則需要對一些控制轉(zhuǎn)移指令進行分析,如goto、switch、以及if相關(guān)的字節(jié)碼指令;步驟(3)根據(jù)java字節(jié)碼指令的分類構(gòu)建字節(jié)碼指令的分類層次架構(gòu)并進行編碼,該架構(gòu)主要分為三層:第一層是java字節(jié)碼指令中除type之外的其余九個大類,第二層是對每個大類進行的詳細子類劃分,第三層則是對應(yīng)的字節(jié)碼指令;步驟(4)對步驟(2)所提取出的兩種粒度(方法粒度、代碼塊粒度)的代碼段(方法或代碼塊)進行特征提取,主要提取的特征包括指令序列is=(i1,i2,i3,...,ii,...,ik)與方法調(diào)用序列mcs={m1,m2,m3,...mi,...,mr},其中k、r為自然數(shù)。在特征提取之后使用字節(jié)碼指令的分類層次架構(gòu)對指令序列進行歸一化處理,將指令序列轉(zhuǎn)化為一級指令序列與二級指令序列,其中一級指令序列對應(yīng)分類層次架構(gòu)中的第一層java字節(jié)碼指令大類,二級指令序列對應(yīng)分類層次架構(gòu)中的第二層java字節(jié)碼指令子類;步驟(5)對于兩個代碼段(方法或代碼塊),利用步驟(4)中得到的指令序列與方法調(diào)用序列,分別進行type-1、type-2克隆檢測與type-3克隆檢測。在type-1、type-2克隆檢測中,首先計算兩個代碼段的二級指令序列的哈希值,如果哈希值相等,再比較兩個代碼段的方法調(diào)用序列,如果方法調(diào)用序列中的方法個數(shù)相同并且每個方法的參數(shù)個數(shù)也相同,則這兩個代碼段為代碼克隆實例。在type-3克隆檢測中,計算兩個代碼段的一級指令序列相似度、二級指令序列相似度與方法調(diào)用序列相似度,然后對一級指令序列相似度、二級指令序列相似度與方法調(diào)用序列相似度進行加權(quán)來確定最終的代碼段相似度值,如果相似度值超過預(yù)先設(shè)定的閾值,則它們?yōu)榇a克隆實例;其中,使用編輯距離計算一級指令序列相似度、二級指令序列相似度;在計算兩個方法調(diào)用序列相似度時,采用遞歸的方式將兩個方法調(diào)用序列的相似度計算轉(zhuǎn)換成這兩個方法調(diào)用序列中每個方法所對應(yīng)的代碼段的相似度的計算;本發(fā)明所提供的云環(huán)境下基于java字節(jié)碼的多粒度的代碼克隆檢測方法由一組功能模塊組成,它們包括:預(yù)處理模塊、特征提取模塊以及代碼克隆檢測模塊。預(yù)處理模塊首先對云環(huán)境中分布于不同地點的java源代碼進行編譯,將其轉(zhuǎn)換為.class文件,進而轉(zhuǎn)換為txt格式的字節(jié)碼文件。隨后在字節(jié)碼文件的基礎(chǔ)上進行方法粒度與塊粒度的代碼段提取。特征提取模塊用于提取代碼段中指令序列與方法調(diào)用序列,并將提取出的指令序列進行歸一化處理。代碼克隆檢測模塊對type-1、type-2克隆與type-3克隆采用不同的方法進行檢測。type-1、type-2克隆檢測主要通過比較指令序列所對應(yīng)的哈希值以及每個方法調(diào)用的參數(shù)個數(shù)來判斷,type-3克隆檢測則主要通過比較指令序列的相似性與方法調(diào)用序列的相似性來判斷。本方明提出的云環(huán)境下基于java字節(jié)碼的多粒度代碼克隆方法,通過對java字節(jié)碼指令進行分析來提取塊粒度的代碼,從而能夠同時檢測方法粒度的克隆與塊粒度的克隆。在計算代碼相似度時,不僅考慮指令之間的相似性同時還引入了方法調(diào)用之間的相似性,從而能夠更好地檢測出語義克隆。與傳統(tǒng)的基于java字節(jié)碼的代碼克隆檢測方法相比,本發(fā)明能夠同時檢測方法粒度與塊粒度的代碼克隆,并且由于加入了方法調(diào)用的相似性比較,本發(fā)明的克隆檢測結(jié)果更加準確。附圖說明圖1本發(fā)明的整體流程圖;圖2代碼塊提取實例圖;圖3為字節(jié)碼分類層次架構(gòu)圖;圖4為特征提取圖;圖5為克隆檢測流程圖。具體實施方式本發(fā)明所提供的云環(huán)境下基于java字節(jié)碼的多粒度代碼克隆檢測方法的具體實施方式主要分3步(如圖1所示):1)預(yù)處理預(yù)處理階段主要包含以下兩個步驟:(1)源代碼編譯首先將云環(huán)境下分布于不同地點的java源代碼編譯為.class文件,并將.class文件轉(zhuǎn)換為txt格式的java字節(jié)碼文件,作為下一步克隆檢測的輸入。每個java字節(jié)碼文件包含一個或多個方法,每個方法都由一系列指令以及相關(guān)的方法調(diào)用構(gòu)成。由于java編譯時會自動處理空行和注釋,同時也去除了變量重命名的影響,所以無需對空行和注釋以及變量名進行預(yù)處理。(2)方法提取與代碼塊提取由于java字節(jié)碼文件將每個java方法單獨解析為一段字節(jié)碼指令,所以提取方法粒度的代碼段時直接讀取每個方法所對應(yīng)的字節(jié)碼指令,而提取塊粒度的代碼段時需要對java字節(jié)碼的控制轉(zhuǎn)移指令進行分析。具體的分析方法為(以圖2為例):a)讀取代碼段所對應(yīng)的字節(jié)碼指令,如果遇到goto指令則讀取該指令的當前編號與跳轉(zhuǎn)編號,然后將當前編號的下一編號與跳轉(zhuǎn)編號之間的指令加入gotoset中。b)如果遇到if指令,若當前編號大于跳轉(zhuǎn)編號,則將gotoset中當前編號與其跳轉(zhuǎn)編號相同的指令移除,并將當前標號與跳轉(zhuǎn)編號的上一編號之間的指令加入到ifreverseset中,否則加入ifset。c)如果在讀取字節(jié)碼指令時遇到switch的分支指令(tableswitch、lookupswitch),將對應(yīng)的跳轉(zhuǎn)指令編號提取出來并添加到numarr中,然后對numarr中的編號從小到大進行遍歷,提取編號所對應(yīng)的字節(jié)碼指令。在提取塊的過程中如果包含switch則遞歸調(diào)用步驟c)。2)特征提取(1)為了在字節(jié)碼的基礎(chǔ)上檢測代碼克隆,需要對字節(jié)碼提取相應(yīng)的特征。本發(fā)明所提取的特征主要是指令序列is和方法調(diào)用序列mcs(如圖3所示)。其中指令序列代表了源代碼的執(zhí)行流程,而方法調(diào)用序列則代表了源代碼中的方法調(diào)用情況。在提取方法調(diào)用序列時,保存了每個方法的參數(shù)調(diào)用個數(shù),用以在克隆檢測階段使用。(2)根據(jù)字節(jié)碼指令的分類層次架構(gòu)(如圖4所示),可以對字節(jié)碼指令序列進行歸一化處理,本發(fā)明將歸一化的結(jié)果分為兩個序列:nis1與nis2。其中nis1是字節(jié)碼指令序列第一層的歸一化結(jié)果(稱為一級指令序列),nis2是字節(jié)碼指令序列第二層歸一化的結(jié)果(稱為二級指令序列)。例如,給定一個字節(jié)碼指令序列(aload_0,new,dup,ldc_w,invokespecial,aload_1,invokevirtual,ldc_w,invokevirtual,invokevirtual,iconst_4,invokevirtual),其第一層的歸一化序列(一級指令序列)為:adeagagdggag,第二層的歸一化序列(二級指令序列)為:a1d1e2a3g3a1g1d2g1g1a3g1。3)代碼克隆檢測代碼克隆檢測過程中將type-3克隆檢測與type-1、type-2的克隆檢測分開以提高代碼克隆檢測的效率(如圖5所示)。在type-1和type-2克隆檢測階段,首先判斷兩個代碼段的二級指令序列是否相同,如果相同則比較方法調(diào)用序列中每個方法以及該方法的參數(shù)個數(shù)是否相同,如果都相同則可以判定為type-1和type-2克隆。在二級指令序列比較階段,為了加快比較速度,同時結(jié)合type-1、type-2克隆的特征,對每個代碼段的二級指令序列計算一個哈希值,如果兩個二級指令序列的哈希值相同,則進一步比較方法調(diào)用序列中每個方法以及該方法的參數(shù)個數(shù)。因為type-1和type2克隆的方法調(diào)用的參數(shù)是一樣的,所以在進行方法調(diào)用序列的比較時,考慮了參數(shù)調(diào)用個數(shù)的一致性。這里用到的哈希算法為java自帶的哈希方法。在type-3克隆檢測階段,分別對指令序列與方法調(diào)用序列進行相似度比較,然后對指令調(diào)用序列相似度與方法調(diào)用序列的相似度進行綜合來確定最終的相似度值。如果總的相似度值大于最小相似度閾值,則對應(yīng)的兩個代碼段為代碼克隆。在指令相似度計算時,使用編輯距離來計算指令之間的相似度,這里的相似度是nis1與nis2的相似度加權(quán)累計值。在方法調(diào)用序列的相似度計算時,采用遞歸的方式將兩個方法調(diào)用序列的相似度計算轉(zhuǎn)換成這兩個方法調(diào)用序列中每個方法所對應(yīng)的代碼段的相似度的計算。本發(fā)明可用于云環(huán)境下java軟件系統(tǒng)的代碼克隆檢測,從而幫助軟件開發(fā)人員更好地對軟件系統(tǒng)進行維護和管理。當前第1頁12當前第1頁12